#include "GameData.h"
#include <sstream>
#include <string>
#include "TileParser.h"
#include "GlobalStructs.h"
#include "SDL_rotozoom.h"
#include "graphicx.h"
#include "Color.h"
#include <utility>
#include <map>
#include "windows.h"
using namespace std;

///////////////////////////// Public Functions /////////////////////////////

/*--- Constructors ---*/
GameData::GameData(SDL_Surface *a_screen)
: m_buffer(a_screen), m_isPressed(false), m_isGrabbed(false), m_windowed(true),
  m_readFile("Configuration Files/TileData.txt"),
  m_btmUI(NULL), m_scrollUI(NULL),m_moveCounter(0),m_playerIsChosenAgain(false),m_playerIsChosen(false),
  m_playerStartedStrongWind(false),m_lastActingPlayer(0),m_roundsCompleted(0),m_gameTimeStart(SDL_GetTicks()),
  m_roundStart(-1), m_drakonSummoner(-1),
  m_titleMusic(NULL),m_gameMusic(NULL),
  m_drakon(NULL),m_destroy(NULL),m_gainCoin(NULL),m_loseCoin(NULL),
  m_playerMove(NULL),m_wind(NULL){
	m_gameBoard = new Board(m_buffer);
	m_oldGameBoard = new Board(m_buffer);
	
	initializeRects();
	Mix_VolumeMusic(32);
	//Mix_VolumeMusic(16);
	//m_gameMusic = Mix_LoadMUS("Audio/music/Sanctuary.wav");
//	m_titleMusic = Mix_LoadMUS("Audio/music/Dearly Beloved.wav");
	//m_titleMusic = Mix_LoadMUS("Audio/music/fft-LionWarIntro.wav");
	m_titleMusic = Mix_LoadMUS("Audio/music/fft-LionWarIntro.wav");
	m_gameMusic = Mix_LoadMUS("Audio/music/wow-st-sw.wav");
	m_endGameMusic1 = Mix_LoadMUS("Audio/music/fft-gameOver.wav");
	m_endGameMusic2 = Mix_LoadMUS("Audio/music/fft-HerosTheme.wav");
//	m_destroy = Mix_LoadWAV("Audio/explode.wav");
	m_destroy = Mix_LoadWAV("Audio/destroyTileWav.wav");
	//m_drakon = Mix_LoadWAV("Audio/firework.wav");
	m_drakon = Mix_LoadWAV("Audio/drakon-moves.wav");
	m_drakonStart = Mix_LoadWAV("Audio/drakon-summoned.wav");
	m_gainCoin = Mix_LoadWAV("Audio/coin2.wav");
	m_loseCoin = Mix_LoadWAV("Audio/coin-drop.wav");
	m_playerMove = Mix_LoadWAV("Audio/footsteps.wav");
	m_magicalShiftWav = Mix_LoadWAV("Audio/magical-shift-swapWav.wav");
	m_teleport = Mix_LoadWAV("Audio/teleport.wav");
	m_mindControl = Mix_LoadWAV("Audio/mindControlWav.wav");
	m_masterKey = Mix_LoadWAV("Audio/masterKeyOpenDoors.wav");
	//m_wind = Mix_LoadWAV("Audio/boing_2.wav");
	m_wind = Mix_LoadWAV("Audio/strongWindWav.wav");
	m_harp = Mix_LoadWAV("Audio/harpWav.wav");
	m_movePlayer = Mix_LoadWAV("Audio/move-player.wav");
	m_dropTileInvalidAreaWav = Mix_LoadWAV("Audio/drop-invalid-area.wav");
	m_placeTileSound = Mix_LoadWAV("Audio/place-tile-sound.wav");
	m_click = Mix_LoadWAV("Audio/click.wav");
	m_endTurnWav = Mix_LoadWAV("Audio/click.wav");
	m_rotateUpWav = Mix_LoadWAV("Audio/rotateUpWav.wav");
	m_rotateDownWav = Mix_LoadWAV("Audio/lefttoright.wav");
	m_rotateStartWav = Mix_LoadWAV("Audio/rotateWav.wav");

	// Start menu
	m_startMenuBG = load_image("Graphics/StartMenuBackground.bmp");
	// Load UI images
	m_btmUI = loadImage("Graphics/UI/menu-bar-bg-bottom.png");
	m_topUI = loadImage("Graphics/UI/menu-bar-bg-top.png");
	m_scrollUI = loadKeyImage("Graphics/UI/scroll.png");
	m_barUI = loadImage("Graphics/UI/bar.png");
	m_font = TTF_OpenFont("Fonts/Dragonfly.ttf",28); // loads the font
	m_font2 = TTF_OpenFont("Fonts/Dragonfly.ttf",35);
	m_font2small = TTF_OpenFont("Fonts/Dragonfly.ttf",25);
	m_font3 = TTF_OpenFont("Fonts/Dragonfly.ttf",20);
	// Load images
	m_tileIcons = load_image("Graphics/Tile Art/tiles.bmp");
	m_tileBGs = load_image("Graphics/Tile Art/Tile Backgrounds.bmp");
	m_boardBG = load_image("Graphics/Game Board Background.bmp");
	m_endGameBG = load_image("Graphics/endGameStatisticsBg.bmp");
	m_chooseAction = load_image("Graphics/ChooseAction.bmp");
	m_confirmationBox = load_image("Graphics/Confirmation Box.bmp");
	m_choosePlayerPic = load_image("Graphics/Choose Player.bmp");
	X_Pic = load_image("Graphics/X.bmp");
	m_arrowsPic = load_image("Graphics/Arrows.bmp");
	m_focusOnActivePlayer = load_image("Graphics/FocusOnActivePlayer.bmp");
	m_endOfTurn = load_image("Graphics/EndOfTurn.bmp");
	m_cancelAction = load_image("Graphics/CancelAction.bmp");
	m_quitButton = load_image("Graphics/QuitButton.bmp");

	setTransparentColor(m_tileIcons,white);
	setTransparentColor(m_tileBGs,white);
	setTransparentColor(m_endGameBG,white);
	setTransparentColor(m_confirmationBox,white);
	setTransparentColor(m_choosePlayerPic,white);
	setTransparentColor(X_Pic,white);
	setTransparentColor(m_arrowsPic,white);
	
	ParseTiles tileParse(m_readFile);
	if(!tileParse.openFile())
	{
		printf("\nError! Cannot open the file.\n\n");
	} else {
		tileParse.readData();
		// Close the file
		tileParse.closeFile();
		if(!tileParse.checkTiles()) {
			printf("\nError! Tile file is formatted incorrectly.");
			printf("\n#Tiles in List [%i] #Valid Tiles [%i]",tileParse.getListSize(),tileParse.getNumValidTiles());
			exit(0);
		}
		m_gameBoard->setDeck(tileParse.getTileData());
		////cout << endl << "List Size: " << m_gameBoard->getDeck().size();

		Tile startTile = m_gameBoard->getDeck().front();
		m_gameBoard->placeStartTile(startTile,Position(BOARD_START_X,BOARD_START_Y));
		m_gameBoard->shuffleDeck(m_gameBoard->getDeck());
		m_currentGameState = TITLE_MENU; // change to title_menu during polishing phase
		m_prevGameState = m_currentGameState;
		m_activePlayer = 0;
	}
	resetValidPlacementArray(); //resetting array
	initializePlayers();
	// GO BACK HERE
	Mix_PlayMusic(m_titleMusic,-1);
}

GameData::~GameData()
{
	// BUGGED
//	delete[] m_totalGold;
//	delete m_gameBoard;
}

void GameData::initializeRects(void) {
	
	m_topUiRect.x = 0; m_topUiRect.w = SCREEN_WIDTH;
	m_topUiRect.y = 0; m_topUiRect.h = 56;
	
	m_bottomUiRect.x = 0; 
	m_bottomUiRect.w = SCREEN_WIDTH;
	m_bottomUiRect.h = 169;
	m_bottomUiRect.y = SCREEN_HEIGHT-m_bottomUiRect.h;

	m_gridUiRect.x = 0; 
	m_gridUiRect.w = SCREEN_WIDTH; 
	m_gridUiRect.y = m_topUiRect.y + m_topUiRect.h; 
	m_gridUiRect.h = SCREEN_HEIGHT - m_bottomUiRect.h - m_topUiRect.h; 
	
	// If exiting the game without using exit(0) will cause a crash pointing
	// to the SDL_Rects' initialization in the GameData constructor. Don't know
	// why it does that...

	// ***Stack Corruption*** ?!?!?!?!?!?!?!?!?!??!?!?!
	// Start menu button placements
	m_menuScreenStartButton.x = 890;
	m_menuScreenStartButton.y = 305;
	m_menuScreenStartButton.w = 155;
	m_menuScreenStartButton.h = 40;

	m_menuScreenExitButton.x = 890;
	m_menuScreenExitButton.y = 442;
	m_menuScreenExitButton.w = 155;
	m_menuScreenExitButton.h = 40;

	// ***MORE CORRUPTION*** ?!?!?!?!?!??!?!?!?!?!?!??!?!?!?!?!??!?!?!?!?!??!?!?
	m_changeTurnScreen.w = 500;
	m_changeTurnScreen.h = 300;
	m_changeTurnScreen.x = (SCREEN_WIDTH/2) - (m_changeTurnScreen.w/2);
	m_changeTurnScreen.y = (SCREEN_HEIGHT/2) - (m_changeTurnScreen.h/2);

	m_chooseActionRect.w = 324;
	m_chooseActionRect.h = 120;
	m_chooseActionRect.x = 20;
	m_chooseActionRect.y = 70;

	m_confirmationRect.w = 150;
	m_confirmationRect.h = 80;
	m_confirmationRect.x = (SCREEN_WIDTH/2) - (m_confirmationRect.w/2);
	m_confirmationRect.y = ((SCREEN_HEIGHT/2) - (m_confirmationRect.w/2)) - 200;

	m_gameStatePos.w = 300;
	m_gameStatePos.h = 30;
	m_gameStatePos.x = (SCREEN_WIDTH/2) - (m_gameStatePos.w/2);
	m_gameStatePos.y = ((SCREEN_HEIGHT/2) - (m_gameStatePos.h/2)) - 270;

	m_choosePlayerRect.w = 300;
	m_choosePlayerRect.h = 100;
	m_choosePlayerRect.x = (SCREEN_WIDTH - m_choosePlayerRect.w) - 50;
	m_choosePlayerRect.y = ((SCREEN_HEIGHT/2) - (m_choosePlayerRect.h/2)) - 230;

	m_arrowsRect.w = 100;
	m_arrowsRect.h = 150;
	m_arrowsRect.x = PLAYER_TILE_LIST_START_X - (m_arrowsRect.w/2);
	m_arrowsRect.y = (Sint16)(PLAYER_TILE_LIST_START_Y + ((TILE_BG_HEIGHT*HAND_TILE_IMAGE_MODIFIER_Y)/2)) - (m_arrowsRect.h/2);
	
	m_focusOnActivePlayerRect.w = 145;
	m_focusOnActivePlayerRect.h = 56;
	m_focusOnActivePlayerRect.x = 750;
	m_focusOnActivePlayerRect.y = 575;

	m_endOfTurnRect.w = 145;
	m_endOfTurnRect.h = 56;
	m_endOfTurnRect.x = (m_focusOnActivePlayerRect.x + m_endOfTurnRect.w)+ 9;
	m_endOfTurnRect.y = 575;
	
	m_cancelActionRect.w = 145;
	m_cancelActionRect.h = 56; 
	m_cancelActionRect.x = 750;
	m_cancelActionRect.y = 640;

	m_quitButtonRect.w = 145;
	m_quitButtonRect.h = 56;
	m_quitButtonRect.x = (m_focusOnActivePlayerRect.x + m_endOfTurnRect.w)+ 9;
	m_quitButtonRect.y = 640;
}

void GameData::initializePlayers(void) {
	m_totalPlayers = m_gameBoard->getNumPlayers();
	m_totalGold = new int[m_totalPlayers+1];

	for(int i=0; i<m_totalPlayers; ++i) { m_totalGold[i] = m_gameBoard->getTotalGold(i); }
	/// configure offsets
	// bottom player hand tile offset
	m_handTileOffset.x = PLAYER_TILE_LIST_START_X;
	m_handTileOffset.y = PLAYER_TILE_LIST_START_Y;
	m_handTileOffset.w = (Uint16)HAND_TILE_IMAGE_MODIFIER_X*TILE_BG_WIDTH*PLAYER_TILE_LIST_DISPLAY_MAX;
	//if(m_gameBoard->getPlayer(m_activePlayer).getHandList().size() > PLAYER_TILE_LIST_DISPLAY_MAX) {
	//	m_handTileOffset.w = (Uint16)HAND_TILE_IMAGE_MODIFIER_X*TILE_BG_WIDTH*PLAYER_TILE_LIST_DISPLAY_MAX;
	//}
	m_handTileOffset.h = (Uint16)HAND_TILE_IMAGE_MODIFIER_Y*TILE_BG_HEIGHT;
	getNeighbors(Position (0,0));
	m_gameBoard->initGameStart();
}

/*--- Game Functions ---*/
/********
Takes in a tile. The function will check where the tile can be placed.
Data will be stored in a type bool 2D array "m_validPlacement[][]"
********/
// returns arrowDirection to harp if valid, and returns NULL_TYPE if invalid
// WARNING! positions may be weird because of Position XY, ROW COLUMN BS
// WARNING 2X! player automatically moves to the first harp in order if more than 1 harp is near he/she
arrowDirection GameData::checkIfHarpIsNear(Position tileCoord, Tile tileToCheck){
	bool harpNearAndMovePossble = false;
	arrowDirection harpMovePossible = NULL_TYPE;
	if(tileToCheck.hasExit(UP) || tileToCheck.getFlag() == MASTER_KEY){
		if( m_gameBoard->getGameTile(tileCoord.getY()-1,tileCoord.getX()).getFlag() == MAGICAL_HARP){
			harpNearAndMovePossble = true;
			harpMovePossible = UP;
		}	
	}
	if(tileToCheck.hasExit(DOWN) || tileToCheck.getFlag() == MASTER_KEY){
		if( m_gameBoard->getGameTile(tileCoord.getY()+1,tileCoord.getX()).getFlag() == MAGICAL_HARP){
			harpNearAndMovePossble = true;
			harpMovePossible = DOWN;
		}	
	}
	if(tileToCheck.hasExit(RIGHT) || tileToCheck.getFlag() == MASTER_KEY){
		if( m_gameBoard->getGameTile(tileCoord.getY(),tileCoord.getX()+1).getFlag() == MAGICAL_HARP){
			harpNearAndMovePossble = true;
			harpMovePossible = RIGHT;
		}	
	}
	if(tileToCheck.hasExit(LEFT) || tileToCheck.getFlag() == MASTER_KEY){
		if( m_gameBoard->getGameTile(tileCoord.getY(),tileCoord.getX()-1).getFlag() == MAGICAL_HARP){
			harpNearAndMovePossble = true;
			harpMovePossible = LEFT;
		}	
	}
	return harpMovePossible;

}
DirGameTileList GameData::getNeighbors(Position columnRow){
	DirGameTileList gametilesNearPos;
	
	
	for(arrowDirection i = UP; i != NULL_TYPE; incArrow(i)){
		if(hasNeighbor(columnRow,i))
			gametilesNearPos.push_back(make_pair(i,getNeighbor(columnRow,i)));
	}
	return gametilesNearPos;
}
bool GameData::canPlace(Tile thisTile, Position columnRow){
	bool canPlaceHere = true;
	/*if(m_gameBoard->getGameTiles()[columnRow.getY()][columnRow.getX()].hasTile()){
		canPlaceHere = false;
	}
*/
	DirGameTileList neighbors = getNeighbors(columnRow);
	if(neighbors.size() > 0){
		for(DirGameTileList::iterator it; it != neighbors.end(); it++){
			
			if(it->second.getTile().getFlag() == TELEPORT || it->second.getTile().getFlag() == MASTER_KEY){
				canPlaceHere = true;
			}
			else{
				if(it->first == UP){
					if(it->second.getTile().hasExit(DOWN))
						canPlaceHere = false;
				}
				else if(it->first == DOWN){
					if(it->second.getTile().hasExit(UP))
						canPlaceHere = false;
				}
				else if(it->first == LEFT){
					if(it->second.getTile().hasExit(RIGHT))
						canPlaceHere = false;
				}
				else if(it->first == RIGHT){
					if(it->second.getTile().hasExit(LEFT))
						canPlaceHere = false;
				}
			}


		}
	} else {
		canPlaceHere = false;
	}
	return canPlaceHere;
}
void GameData::checkValidPlacement(Tile a_tile) {
	bool neighbors[4];
	bool up = true, right = true, down = true, left = true;
	int rowMin,rowMax,columnMin,columnMax;
	rowMin = 0;
	rowMax = BOARD_ARRAY_SIZE;
	columnMin = 0;
	columnMax = BOARD_ARRAY_SIZE;
	
	if(rowMin >= 0) {
	} else {
		rowMin = 0;
	}
	if(rowMax <= BOARD_ARRAY_SIZE-1) {
	} else {
		rowMax = BOARD_ARRAY_SIZE;
	}

	if(columnMin >= 0) {
	} else {
		columnMin = 0;
	}
	if(columnMax <= BOARD_ARRAY_SIZE-1) {
	} else {
		columnMax = BOARD_ARRAY_SIZE;
	}

	for(int r = rowMin; r < rowMax; ++r) {
		for(int c = columnMin; c < columnMax; ++c) {
			up = true;
			right = true;
			down = true;
			left = true;
			// Check to see if the questioned tile has a neighbor and is not on an existing tile
			if(!m_gameBoard->getGameTiles()[r][c].hasTile() && hasNeighbor(r,c)) {
				getNeighbors(neighbors,r,c);
				if(neighbors[0] == true && a_tile.hasExit(UP) == true) {
					if(m_gameBoard->getGameTile(r-1,c).hasExit(DOWN) == true) {
						up = false;
					} else {
						up = true;
					}
				} else {
					up = true;
				}
				if(neighbors[1] == true && a_tile.hasExit(RIGHT) == true) {
					if(m_gameBoard->getGameTile(r,c+1).hasExit(LEFT) == true) {
						right = false;
					} else {
						right = true;
					}
				} else {
					right = true;
				}
				if(neighbors[2] == true && a_tile.hasExit(DOWN) == true) {
					if(m_gameBoard->getGameTile(r+1,c).hasExit(UP) == true) {
						down = false;
					} else {
						down = true;
					}
				} else {
					down = true;
				}
				if(neighbors[3] == true && a_tile.hasExit(LEFT) == true) {
					if(m_gameBoard->getGameTile(r,c-1).hasExit(RIGHT) == true) {
						left = false;
					} else {
						left = true;
					}
				} else {
					left = true;
				}

				if(up == true && right == true && down == true && left == true) {
					m_validPlacement[r][c] = true;
				} else {
					m_validPlacement[r][c] = false;
				}
			} else {
			} // has a neighbor and is not on a tile
		}
	}
	
}
void GameData::checkValidPlacement2(Tile a_tile) {
	//////cout << endl << "Tile Exits: U[" << a_tile.hasExit(UP) << "]R[" << a_tile.hasExit(RIGHT)
	//				<< "]D[" << a_tile.hasExit(DOWN) << "]L[" << a_tile.hasExit(LEFT) << "]";
	bool neighbors[4];
	bool up = true, right = true, down = true, left = true;
	int rowMin,rowMax,columnMin,columnMax;
	rowMin = 0;
	rowMax = BOARD_ARRAY_SIZE;
	columnMin = 0;
	columnMax = BOARD_ARRAY_SIZE;
	
	if(rowMin >= 0) {
	} else {
		rowMin = 0;
	}
	if(rowMax <= BOARD_ARRAY_SIZE-1) {
	} else {
		rowMax = BOARD_ARRAY_SIZE;
	}

	if(columnMin >= 0) {
	} else {
		columnMin = 0;
	}
	if(columnMax <= BOARD_ARRAY_SIZE-1) {
	} else {
		columnMax = BOARD_ARRAY_SIZE;
	}

	for(int r = rowMin; r < rowMax; ++r) {
		for(int c = columnMin; c < columnMax; ++c) {
			up = true;
			right = true;
			down = true;
			left = true;
			// Check to see if the questioned tile has a neighbor
			if(hasNeighbor(r,c)) {
				getNeighbors(neighbors,r,c);
				if(neighbors[0] == true && a_tile.hasExit(UP) == true) {
					if(m_gameBoard->getGameTile(r-1,c).hasExit(DOWN) == true) {
						up = false;
					} else {
						up = true;
					}
				} else {
					up = true;
				}
				if(neighbors[1] == true && a_tile.hasExit(RIGHT) == true) {
					if(m_gameBoard->getGameTile(r,c+1).hasExit(LEFT) == true) {
						right = false;
					} else {
						right = true;
					}
				} else {
					right = true;
				}
				if(neighbors[2] == true && a_tile.hasExit(DOWN) == true) {
					if(m_gameBoard->getGameTile(r+1,c).hasExit(UP) == true) {
						down = false;
					} else {
						down = true;
					}
				} else {
					down = true;
				}
				if(neighbors[3] == true && a_tile.hasExit(LEFT) == true) {
					if(m_gameBoard->getGameTile(r,c-1).hasExit(RIGHT) == true) {
						left = false;
					} else {
						left = true;
					}
				} else {
					left = true;
				}

				if(up == true && right == true && down == true && left == true) {
					m_validPlacement[r][c] = true;
				} else {
					m_validPlacement[r][c] = false;
				}
			} else {
			} // has a neighbor
		}
	}
}
void GameData::checkValidPlacement3(Tile a_tile) {
	bool neighbors[4];
	bool up = true, right = true, down = true, left = true;
	int rowMin,rowMax,columnMin,columnMax;
	rowMin = 0;
	rowMax = BOARD_ARRAY_SIZE;
	columnMin = 0;
	columnMax = BOARD_ARRAY_SIZE;
	
	/* check Borders */ 
	if(rowMin < 0) rowMin = 0;
	if(rowMax > BOARD_ARRAY_SIZE -1) rowMax = BOARD_ARRAY_SIZE;
	if(columnMin < 0) columnMin = 0;
	if(columnMax > BOARD_ARRAY_SIZE - 1) columnMax = BOARD_ARRAY_SIZE;
	
	for(int r = rowMin; r < rowMax; ++r) {
		for(int c = columnMin; c < columnMax; ++c) {
			/* reset neighbors: true */ 
			up = true;
			right = true;
			down = true;
			left = true;

			// Check to see if the questioned tile has a neighbor and is on an existing tile
			if(m_gameBoard->getGameTiles()[r][c].hasTile() && hasNeighbor(r,c)) {
				getNeighbors(neighbors,r,c);
				if(neighbors[0] == true && a_tile.hasExit(UP) == true) {
					if(m_gameBoard->getGameTile(r-1,c).hasExit(DOWN) == true) {
						up = false;
					} else {
						up = true;
					}
				} else {
					up = true;
				}
				if(neighbors[1] == true && a_tile.hasExit(RIGHT) == true) {
					if(m_gameBoard->getGameTile(r,c+1).hasExit(LEFT) == true) {
						right = false;
					} else {
						right = true;
					}
				} else {
					right = true;
				}
				if(neighbors[2] == true && a_tile.hasExit(DOWN) == true) {
					if(m_gameBoard->getGameTile(r+1,c).hasExit(UP) == true) {
						down = false;
					} else {
						down = true;
					}
				} else {
					down = true;
				}
				if(neighbors[3] == true && a_tile.hasExit(LEFT) == true) {
					if(m_gameBoard->getGameTile(r,c-1).hasExit(RIGHT) == true) {
						left = false;
					} else {
						left = true;
					}
				} else {
					left = true;
				}

				if(up == true && right == true && down == true && left == true ) {
					m_validPlacement[r][c] = true;
				} else {
					m_validPlacement[r][c] = false;
				}
			} else {
			} // has a neighbor and is on a tile
		}
	}
	// go thru each tile to see if it has a player standing on it
	for(int r = rowMin; r < rowMax; ++r) {
		for(int c = columnMin; c < columnMax; ++c) {
			if(m_gameBoard->isThereAPlayerOnGameTile(r,c)) m_validPlacement[r][c] = false;
		}
	}
	m_validPlacement[BOARD_START_Y][BOARD_START_X] = false;
}
void GameData::updateDrakonTerror(){

	if(m_gameBoard->isDrakonPlaced()){
		Position drakonsPosition = m_gameBoard->getPlayer(NUMBER_OF_PLAYERS).getPosition();
		list<int> playersInSameTileAsDrakon;
		for(int i = 0; i < NUMBER_OF_PLAYERS; ++i){
			Position heroPos = m_gameBoard->getPlayer(i).getPosition();
			if(drakonsPosition.equals(heroPos)){
				//playersInSameTileAsDrakon.push_back(heroPos);
				playersInSameTileAsDrakon.push_back(i);
				// for each player where drakon is standing, move to start position
				m_gameBoard->getPlayer(i).setPos(Position(BOARD_START_X,BOARD_START_Y));
			}
			

		}
		// check if there is more than one hero where drakon is standing if so, all players loose gold
		if(playersInSameTileAsDrakon.size() == 1){
			m_gameBoard->getPlayer(playersInSameTileAsDrakon.front()).addAffectInfo(m_playerIsChosen?m_chosenPlayer:m_activePlayer,MOVE_DRAKON);
			m_gameBoard->getPlayer(playersInSameTileAsDrakon.front()).getCoinSack().removeCoin();

		}
		else if(playersInSameTileAsDrakon.size() > 1){
			for(int i = 0; i < NUMBER_OF_PLAYERS; ++i){
				// GOLD CACHE NOT HANDLED, is it in rules?
				m_gameBoard->getPlayer(i).addAffectInfo(m_playerIsChosen?m_chosenPlayer:m_activePlayer,MOVE_DRAKON);
				m_gameBoard->getPlayer(i).getCoinSack().removeCoin();
			}
		}
	}
}
void GameData::updateConfirmAction(){
	if(isWithinRect(m_mPos.getX(),m_mPos.getY(),m_confirmationRect)) {
		Mix_PlayChannel(-1,m_click,0);
			if(m_mPos.getX() <= m_confirmationRect.x + (m_confirmationRect.w/2)) {
				SDL_FreeSurface(m_confirmationBox);
				m_confirmationBox = load_image("Graphics/Confirmation Box 1.bmp");
				setTransparentColor(m_confirmationBox,white);
			} else if(m_mPos.getX() > m_confirmationRect.x + (m_confirmationRect.w/2)) {
				SDL_FreeSurface(m_confirmationBox);
				m_confirmationBox = load_image("Graphics/Confirmation Box 2.bmp");
				setTransparentColor(m_confirmationBox,white);
			}
		} else {
			SDL_FreeSurface(m_confirmationBox);
			m_confirmationBox = load_image("Graphics/Confirmation Box.bmp");
			setTransparentColor(m_confirmationBox,white);
		}
}
void GameData::updateCamera(){
	if(m_mPos.getX() <= CAM_MOVE_THRESHOLD && m_mPos.getX() >= 0) {
		int x = m_gameBoard->getGridStart().getX();
		int y = m_gameBoard->getGridStart().getY();
		x += CAM_MOVE_SPEED;
		m_gameBoard->setGridStart(y,x);
	}
	if(m_mPos.getX() >= SCREEN_WIDTH-CAM_MOVE_THRESHOLD && m_mPos.getX() <= SCREEN_WIDTH) {
		int x = m_gameBoard->getGridStart().getX();
		int y = m_gameBoard->getGridStart().getY();
		x -= CAM_MOVE_SPEED;
		m_gameBoard->setGridStart(y,x);
	}
	if(m_mPos.getY() <= CAM_MOVE_THRESHOLD && m_mPos.getY() >= 0) {
		int x = m_gameBoard->getGridStart().getX();
		int y = m_gameBoard->getGridStart().getY();
		y += CAM_MOVE_SPEED;
		m_gameBoard->setGridStart(y,x);
	}
	if(m_mPos.getY() >= SCREEN_HEIGHT-CAM_MOVE_THRESHOLD && m_mPos.getY() <= SCREEN_HEIGHT) {
		int x = m_gameBoard->getGridStart().getX();
		int y = m_gameBoard->getGridStart().getY();
		y -= CAM_MOVE_SPEED;
		m_gameBoard->setGridStart(y,x);
	}
}
void GameData::updateSelectAPlayerWhileChosen(){
		Position playerPosition = m_gameBoard->getPlayer(m_lastActingPlayer).getPosition();
		Tile tileOfgameTilewherePlayeris = m_gameBoard->getGameTile(playerPosition.getY(),playerPosition.getX());
		if(tileOfgameTilewherePlayeris.getFlag() == MAP_TILE){
			Mix_PlayChannel(-1,m_mindControl,0);
			stealPlayerRandomTile(m_lastActingPlayer,m_chosenPlayer);
			m_gameBoard->getPlayer(m_chosenPlayer).addAffectInfo(m_lastActingPlayer,MAP_TILE);
			m_playerIsChosen = false;
			changeTurn(); 
		}
		else if(tileOfgameTilewherePlayeris.getFlag() == MIND_CONTROL){
			Player chosenPlayer = m_gameBoard->getPlayer(m_chosenPlayer);
			
			Position chosenPlayerPos = chosenPlayer.getPosition();
			
			Tile tileOfgameTilewhereOtherPlayeris = m_gameBoard->getGameTile(chosenPlayerPos.getY(),chosenPlayerPos.getX());


			if(tileOfgameTilewhereOtherPlayeris.getFlag() == STRONG_WIND){
				if(canMoveTwice(chosenPlayerPos)){
					m_moveCounter = 2;
					m_prevGameState = m_currentGameState;
					m_gameBoard->getPlayer(m_chosenPlayer).addAffectInfo(m_lastActingPlayer,STRONG_WIND);
					m_currentGameState = MOVE_OTHER_PLAYER;
					m_playerStartedStrongWind = true;
				}
				else{
					m_playerIsChosen = false;
					changeTurn();
	 			}
			} 
			else {
				m_moveCounter = 1;
				m_prevGameState = m_currentGameState;
				m_currentGameState = MOVE_OTHER_PLAYER;
			}

			m_gameBoard->getPlayer(m_chosenPlayer).addAffectInfo(m_lastActingPlayer,MIND_CONTROL);
			
			
		}
}
void GameData::updateMovePlayer(){
	Position playerPosition = m_gameBoard->getPlayer(m_activePlayer).getPosition();
		Tile tileOfgameTilewherePlayeris = m_gameBoard->getGameTile(playerPosition.getY(),playerPosition.getX());
		arrowDirection moveToHarp = checkIfHarpIsNear(playerPosition,tileOfgameTilewherePlayeris);
		// must be in a separate if statement
		if(m_moveCounter <= 0){
			m_prevGameState = m_currentGameState;
			m_currentGameState = MOVE_PLAYER_CLEAN_UP;
		}
		else if(tileOfgameTilewherePlayeris.getFlag() == STRONG_WIND){
			if(!m_moveSoundPlayed){
				m_moveSoundPlayed  = true;
				Mix_PlayChannel(-1,m_wind,0);
			}
		}
		else if(tileOfgameTilewherePlayeris.getFlag() == MASTER_KEY){
			if(!m_moveSoundPlayed){
				m_moveSoundPlayed = true;
				Mix_PlayChannel(-1,m_masterKey,0);
			}
		}
	
		if(tileOfgameTilewherePlayeris.getFlag() == TELEPORT && !m_playerStartedStrongWind){
			m_prevGameState = m_currentGameState;
			m_currentGameState = SELECT_GAMETILE;
		}
		else if(moveToHarp != NULL_TYPE && tileOfgameTilewherePlayeris.getFlag() != TELEPORT){
			switch(moveToHarp){
				case UP:
					movePlayerUP(m_activePlayer); 
					//Mix_PlayChannel(-1,m_playerMove,0);
					break;
				case DOWN:
					movePlayerDOWN(m_activePlayer);
					//Mix_PlayChannel(-1,m_playerMove,0);
					break;
				case LEFT:
					movePlayerLEFT(m_activePlayer);
					//Mix_PlayChannel(-1,m_playerMove,0);
					break;
				case RIGHT:
					movePlayerRIGHT(m_activePlayer);
					//Mix_PlayChannel(-1,m_playerMove,0);
					break;
				default:
					break;

			}
			Mix_PlayChannel(-1,m_harp,0);
			m_moveCounter--;
			m_prevGameState = m_currentGameState;;
			if(m_moveCounter == 0){
				m_currentGameState = MOVE_PLAYER_CLEAN_UP;
			}
			
		}
}
void GameData::updateMoveOtherPlayer(){
		// check if player is drakon when he is summoned else do normal move other player movements

		if(m_chosenPlayer == NUMBER_OF_PLAYERS && m_gameBoard->isDrakonPlaced())

		{
			if(m_moveCounter <= 0){
					m_prevGameState = m_currentGameState;
				m_currentGameState = MOVE_OTHER_PLAYER_CLEAN_UP;
			}
		}
		else{
			Position playerPosition = m_gameBoard->getPlayer(m_chosenPlayer).getPosition();
			Tile tileOfgameTilewherePlayeris = m_gameBoard->getGameTile(playerPosition.getY(),playerPosition.getX());
			//cout << "in MOVE_OTHER_PLAYER\n";
			//cout << "tileOfgameTilewherePlayeris = " << tileOfgameTilewherePlayeris.toString() << endl;
			//cout << "tile flag = " << tileOfgameTilewherePlayeris.getFlag()  << endl;
			//cout << "m_MoveCounter = " << m_moveCounter << endl;

			arrowDirection moveToHarp = checkIfHarpIsNear(playerPosition,tileOfgameTilewherePlayeris);

			// go to clean up if counter is 0
			if(m_moveCounter <= 0){
					m_prevGameState = m_currentGameState;
				m_currentGameState = MOVE_OTHER_PLAYER_CLEAN_UP;
			}
			// else player still has moves, check for harp
			else{
				
				if(moveToHarp != NULL_TYPE && tileOfgameTilewherePlayeris.getFlag() != TELEPORT){
					switch(moveToHarp){
						case UP:
							movePlayerUP(m_chosenPlayer); 
							
							break;
						case DOWN:
							movePlayerDOWN(m_chosenPlayer);
							break;
						case LEFT:
							movePlayerLEFT(m_chosenPlayer);
							break;
						case RIGHT:
							movePlayerRIGHT(m_chosenPlayer);
							break;
						default:
							//cout << "m_chosenPlayer: ERROR INVALID MOVE STATE TO HARP\n";
							break;
					}
					Mix_PlayChannel(-1,m_harp,0);
					m_moveCounter--;
					m_prevGameState = m_currentGameState;
				}

				// if player has not started as strong wind handle normal cases
				if(!m_playerStartedStrongWind){
					if(tileOfgameTilewherePlayeris.getFlag() == TELEPORT){
						m_prevGameState = m_currentGameState;
						m_currentGameState = SELECT_GAMETILE;
						m_playerIsChosen = true;
					}	

				}
			
			}
		}
}
void GameData::updatePlaceTileCleanUp(){
	// WARNING FIX ESCAPE TILE TO REDIRECT HERE
	//cout << "In player place tile clean up\n";
	// use for drakon moves
	

	Position playerPosition = m_gameBoard->getPlayer(m_activePlayer).getPosition();
	// get gameTile of that position
	Tile tileOfgameTilewherePlayeris = m_gameBoard->getGameTile(playerPosition.getY(),playerPosition.getX());
	
	if(m_grabbedTile.getFlag() == MOVE_DRAKON && !m_gameBoard->isDrakonPlaced()){
		m_prevGameState = m_currentGameState;
		m_currentGameState = SELECT_GAMETILE;
	}
	else if(m_grabbedTile.getFlag() == ESCAPE_TILE){
		m_prevGameState = m_currentGameState;
		m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).setPos(m_grabbedTilePos);
	}
	else{
		
		
		changeTurn();
	}
	
}
void GameData::updateMoveOtherPlayerCleanUp(){
	Position playerPosition = m_gameBoard->getPlayer(m_chosenPlayer).getPosition();
	// get gameTile of that position
	Tile tileOfgameTilewherePlayeris = m_gameBoard->getGameTile(playerPosition.getY(),playerPosition.getX());
	int playerFlag = tileOfgameTilewherePlayeris.getFlag();

	// First check if that player is drakon
	// dont do any tile clean up phases if he is drakon
	if(m_chosenPlayer == NUMBER_OF_PLAYERS){
		updateDrakonTerror();
		changeTurn();
	}
	else{
		switch(playerFlag){
			case FIND_GOLD:{
				
				CoinSack playersCoinSack = m_gameBoard->getPlayer(m_chosenPlayer).getCoinSack();
				Position currentPlayerPos = m_gameBoard->getPlayer(m_activePlayer).getPosition();
				int gameTileOwner = m_gameBoard->getGameTiles()[currentPlayerPos.getY()][currentPlayerPos.getX()].getOwner();
				m_gameBoard->getPlayer(m_chosenPlayer).addAffectInfo(gameTileOwner,FIND_GOLD);
				playersCoinSack.addCoin();
				
				m_gameBoard->getPlayer(m_chosenPlayer).setCoinSack(playersCoinSack);
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,FIND_GOLD);
				changeTurn();
				
						   }
				break;
			case LOSE_A_COIN:{

				Position currentPlayerPos = m_gameBoard->getPlayer(m_activePlayer).getPosition();
				int gameTileOwner = m_gameBoard->getGameTiles()[currentPlayerPos.getY()][currentPlayerPos.getX()].getOwner();
				m_gameBoard->getPlayer(m_chosenPlayer).addAffectInfo(gameTileOwner,LOSE_A_COIN);

				CoinSack playersCoinSack = m_gameBoard->getPlayer(m_chosenPlayer).getCoinSack();
				playersCoinSack.removeCoin();
				m_gameBoard->getPlayer(m_chosenPlayer).setCoinSack(playersCoinSack);
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,LOSE_A_COIN);
				changeTurn();
							 }
				break;
			case STEAL_GOLD_CW:{
				int playerNumToStealGold = m_chosenPlayer + 1;
				// check if number is more than last player, if so, set back to 0
				if(playerNumToStealGold == NUMBER_OF_PLAYERS) playerNumToStealGold = 0;
				GoldValues stolenCoin = m_gameBoard->getPlayer(playerNumToStealGold).getCoinSack().removeCoin();
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,STEAL_GOLD_CW);
				if(stolenCoin != GV_NULL){
					m_gameBoard->getPlayer(playerNumToStealGold).addAffectInfo(m_chosenPlayer,STEAL_GOLD_CW);
					m_gameBoard->getPlayer(m_chosenPlayer).getCoinSack().addCoin(stolenCoin);
				}
				changeTurn();
							 }
				break;
			case STEAL_GOLD_CCW:{
				int playerNumToStealGold = m_chosenPlayer - 1;
				// check if number is more than last player, if so, set back to 0
				if(playerNumToStealGold < 0) playerNumToStealGold = NUMBER_OF_PLAYERS-1;
				GoldValues stolenCoin = m_gameBoard->getPlayer(playerNumToStealGold).getCoinSack().removeCoin();
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,STEAL_GOLD_CCW);
				if(stolenCoin != GV_NULL){
					m_gameBoard->getPlayer(playerNumToStealGold).addAffectInfo(m_chosenPlayer ,STEAL_GOLD_CCW);
					m_gameBoard->getPlayer(m_chosenPlayer).getCoinSack().addCoin(stolenCoin);
				}
				changeTurn();
								}
				break;
			case FLOATING_TILE:{
				m_prevGameState = m_currentGameState;
				m_currentGameState = PLACE_FLOATING_TILE;
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,FLOATING_TILE);
				m_grabbedTilePos = m_gameBoard->getPlayer(m_chosenPlayer).getPosition();
				m_grabbedTile = m_gameBoard->getGameTiles()[m_grabbedTilePos.getY()][m_grabbedTilePos.getX()].popTile();
							  }
				break;
			case DESTROY_TILE:{
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,DESTROY_TILE);
				Mix_PlayChannel(-1,m_destroy,0);
				
				m_prevGameState = m_currentGameState;
				m_currentGameState = SELECT_GAMETILE;
							  }
				break;
			case ROTATE_TILE:{
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,ROTATE_TILE);
				m_prevGameState = m_currentGameState;
				m_currentGameState = SELECT_GAMETILE;
							 }
				break;
			case MAGICAL_SHIFT:{
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,MAGICAL_SHIFT);
				m_prevGameState = m_currentGameState;
				m_currentGameState = MAGICAL_SHIFT_STATE;			
							   }
				break;
			case MAP_TILE:{
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,MAP_TILE);
				m_prevGameState = m_currentGameState;
				m_playerIsChosen = false;
				m_lastActingPlayer = m_chosenPlayer;
				m_currentGameState = SELECT_A_PLAYER;			
						  }
				break;
			case MIND_CONTROL:{
				Mix_PlayChannel(-1,m_mindControl,0);
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,MIND_CONTROL);
				m_prevGameState = m_currentGameState;
				m_playerIsChosen = false;
				m_lastActingPlayer = m_chosenPlayer;
				m_currentGameState = SELECT_A_PLAYER;
							  }
				break;
			case MOVE_DRAKON:{	//11
				if(!m_gameBoard->isDrakonPlaced()){
					m_prevGameState = m_currentGameState;
					m_currentGameState = SELECT_GAMETILE;
				}
				else{
					m_chosenPlayer = NUMBER_OF_PLAYERS;
					bool m_playerIsChosen = true;
					m_prevGameState = m_currentGameState;
					m_currentGameState = MOVE_OTHER_PLAYER;
					m_moveCounter = 3;

				}
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,MOVE_DRAKON);
							 
							 }
				break;
			case MAGICAL_HARP:
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,MAGICAL_HARP);
				changeTurn();
				break;
			case STRONG_WIND:
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,STRONG_WIND);
				changeTurn();
				break;
			case TELEPORT:
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,TELEPORT);
				changeTurn();
				break;
			case START_TILE_ID:
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,START_TILE_ID);
				changeTurn();
				break;
			case EMPTY_TILE:
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,EMPTY_TILE);
				changeTurn();
				break;
			case MASTER_KEY:
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,MASTER_KEY);
				changeTurn();
				break;
			case ESCAPE_TILE:
				m_gameBoard->getPlayer(m_chosenPlayer).addAction(false,ESCAPE_TILE);
				changeTurn();
				break;
				changeTurn();
				break;
			default:
				cout << "ERROR move other player clean up not handled. TileFlag= " << playerFlag << endl;
				break;						  
		}
	}
}
void GameData::updateEndGame(){
	
	m_gameTimeEnd = SDL_GetTicks();
	m_currentEndGameMusic = 0;
	
}
void GameData::updateEndGameStatistics(){
	if(!Mix_PlayingMusic()){ 
		Mix_HaltMusic();
		Mix_PlayMusic(m_titleMusic,-1);
	}
	//
	/*if(!Mix_PlayingMusic() && m_currentEndGameMusic == 0) {
		m_currentEndGameMusic++;
		Mix_PlayMusic(m_endGameMusic2,-1);
	}
	else if(!Mix_PlayingMusic() && m_currentEndGameMusic == 1) {
		m_currentEndGameMusic++;
		Mix_PlayMusic(m_titleMusic,1);
	}
	if(!Mix_PlayingMusic()&& m_currentEndGameMusic == 2) {
		m_currentEndGameMusic = 0;
		Mix_PlayMusic(m_endGameMusic1,-1);
	}*/
	
}
void GameData::update() {
	/* updates handlist info for drawPlayerHand() */ 
	// WARNING DURING MC
	// Only for m_isGrabbed
	
	m_handTileOffset.w = HAND_TILE_IMAGE_MODIFIER_X*TILE_BG_WIDTH*m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).getHandList().size();
	m_handTileOffset.h = HAND_TILE_IMAGE_MODIFIER_Y*TILE_BG_HEIGHT;
//	cout << toString(m_handTileOffset) << endl;
	if(m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).getHandList().size() > PLAYER_TILE_LIST_DISPLAY_MAX) {
		m_handTileOffset.w = HAND_TILE_IMAGE_MODIFIER_X*TILE_BG_WIDTH*PLAYER_TILE_LIST_DISPLAY_MAX;
	}
	/* END: updates handlist info for drawPlayerHand() */ 
	if(isAnyState(CONFIRM_ACTION)) {
		updateConfirmAction();
	}
	if(isNoneOfState(TITLE_MENU,PLAYER_TURN_CHANGE,END_GAME_STATISTICS)) {
		updateCamera();
	}

// UPDATE DEPENDING ON STATE
	switch(m_currentGameState){
		case SELECT_A_PLAYER: if(!m_playerIsChosenAgain && m_playerIsChosen)updateSelectAPlayerWhileChosen()	; break;
		case PLACE_TILE_CLEAN_UP:						updatePlaceTileCleanUp()			; break;
		case MOVE_PLAYER:								updateMovePlayer()					; break;
		case MOVE_OTHER_PLAYER:							updateMoveOtherPlayer()				; break;
		case MOVE_PLAYER_CLEAN_UP:						updateMovePlayerCleanUp()			; break;
		case MOVE_OTHER_PLAYER_CLEAN_UP:				updateMoveOtherPlayerCleanUp()		; break;
		case END_GAME:									updateEndGame()						; break;
		case END_GAME_STATISTICS:						updateEndGameStatistics()			; break;
		
	}		
}
void GameData::updateMovePlayerCleanUp(){
		Position playerPosition = m_gameBoard->getPlayer(m_activePlayer).getPosition();
		// get gameTile of that position
		Tile tileOfgameTilewherePlayeris = m_gameBoard->getGameTile(playerPosition.getY(),playerPosition.getX());
		int playerFlag = tileOfgameTilewherePlayeris.getFlag();
		switch(playerFlag){
			case FIND_GOLD:		//1
				{ // Find Gold
					Position currentPlayerPos = m_gameBoard->getPlayer(m_activePlayer).getPosition();
					int gameTileOwner = m_gameBoard->getGameTiles()[currentPlayerPos.getY()][currentPlayerPos.getX()].getOwner();
					m_gameBoard->getPlayer(m_activePlayer).addAffectInfo(gameTileOwner,FIND_GOLD);
					CoinSack playersCoinSack = m_gameBoard->getPlayer(m_activePlayer).getCoinSack();
					playersCoinSack.addCoin();
					m_gameBoard->getPlayer(m_activePlayer).setCoinSack(playersCoinSack);
					m_gameBoard->getPlayer(m_activePlayer).addAction(false,FIND_GOLD);
					changeTurn();
				}
				Mix_PlayChannel(-1,m_gainCoin,0);
				break;
			case LOSE_A_COIN:	//2
				{
					Position currentPlayerPos = m_gameBoard->getPlayer(m_activePlayer).getPosition();
					CoinSack playersCoinSack = m_gameBoard->getPlayer(m_activePlayer).getCoinSack();
					
					int gameTileOwner = m_gameBoard->getGameTiles()[currentPlayerPos.getY()][currentPlayerPos.getX()].getOwner();
					playersCoinSack.removeCoin();
					m_gameBoard->getPlayer(m_activePlayer).addAffectInfo(gameTileOwner,LOSE_A_COIN);
					m_gameBoard->getPlayer(m_activePlayer).setCoinSack(playersCoinSack);
					m_gameBoard->getPlayer(m_activePlayer).addAction(false,LOSE_A_COIN);
					changeTurn();
				}
				Mix_PlayChannel(-1,m_loseCoin,0);
				break;
			case STEAL_GOLD_CW:	{//3
				int playerNumToStealGold = m_activePlayer + 1;
				// check if number is more than last player, if so, set back to 0
				if(playerNumToStealGold == NUMBER_OF_PLAYERS) playerNumToStealGold = 0;
				GoldValues stolenCoin = m_gameBoard->getPlayer(playerNumToStealGold).getCoinSack().removeCoin();
				m_gameBoard->getPlayer(m_activePlayer).addAction(false,STEAL_GOLD_CW);
				if(stolenCoin != GV_NULL){
					m_gameBoard->getPlayer(m_activePlayer).getCoinSack().addCoin(stolenCoin);
					m_gameBoard->getPlayer(playerNumToStealGold).addAffectInfo(m_activePlayer,STEAL_GOLD_CW);
				}
				changeTurn();
								}
				Mix_PlayChannel(-1,m_loseCoin,0);
				break;
			case STEAL_GOLD_CCW://4
				{
					int playerNumToStealGold = m_activePlayer - 1;
					// check if number is more than last player, if so, set back to NUMBER_OF_PLAYERS-1;
					if(playerNumToStealGold < 0) playerNumToStealGold = NUMBER_OF_PLAYERS-1;
					GoldValues stolenCoin = m_gameBoard->getPlayer(playerNumToStealGold).getCoinSack().removeCoin();
					m_gameBoard->getPlayer(m_activePlayer).addAction(false,STEAL_GOLD_CCW);
					if(stolenCoin != GV_NULL){
						m_gameBoard->getPlayer(playerNumToStealGold).addAffectInfo(m_activePlayer,STEAL_GOLD_CCW);
						m_gameBoard->getPlayer(m_activePlayer).getCoinSack().addCoin(stolenCoin);
					}
					changeTurn();
				}
				Mix_PlayChannel(-1,m_loseCoin,0);
				break;
			case FLOATING_TILE:	//7
				{

					m_prevGameState = m_currentGameState;
					m_currentGameState = PLACE_FLOATING_TILE;
					m_grabbedTilePos = m_gameBoard->getPlayer(m_activePlayer).getPosition();
					Position currentPlayerPos =  m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).getPosition();
					int gameTileOwner = m_gameBoard->getGameTiles()[currentPlayerPos.getY()][currentPlayerPos.getX()].getOwner();
					m_gameBoard->getPlayer(m_activePlayer).addAffectInfo(gameTileOwner,FLOATING_TILE);
					m_gameBoard->getPlayer(m_activePlayer).addAction(false,FLOATING_TILE);

					m_grabbedTile = m_gameBoard->getGameTiles()[m_grabbedTilePos.getY()][m_grabbedTilePos.getX()].popTile();
				}
				Mix_PlayChannel(-1,m_teleport,0);
				break;
			case DESTROY_TILE:{	//9
					m_prevGameState = m_currentGameState;
					m_gameBoard->getPlayer(m_activePlayer).addAction(false,DESTROY_TILE);
					m_currentGameState = SELECT_GAMETILE;
							  }
			  
				break;

			
			case MOVE_DRAKON:{	//11
				if(!m_gameBoard->isDrakonPlaced()){
					m_prevGameState = m_currentGameState;
					m_currentGameState = SELECT_GAMETILE;
				}
				else{
					m_chosenPlayer = NUMBER_OF_PLAYERS;
					bool m_playerIsChosen = true;
					m_prevGameState = m_currentGameState;
					m_currentGameState = MOVE_OTHER_PLAYER;
					m_moveCounter = 3;

				}
				Mix_PlayChannel(-1,m_drakon,0);
				m_gameBoard->getPlayer(m_activePlayer).addAction(false,MOVE_DRAKON);
							 
							 }
				break;
			
			case ROTATE_TILE:{	//13
				m_prevGameState = m_currentGameState;
				m_currentGameState = SELECT_GAMETILE;
				m_gameBoard->getPlayer(m_activePlayer).addAction(false,ROTATE_TILE);
							 }

				break;
			case MAP_TILE:		//15
				m_prevGameState = m_currentGameState;
				m_lastActingPlayer = m_activePlayer;
				m_gameBoard->getPlayer(m_activePlayer).addAction(false,MAP_TILE);
				m_currentGameState = SELECT_A_PLAYER;
				break;
			
			case MAGICAL_SHIFT:	{//17
				m_prevGameState = m_currentGameState;
				m_gameBoard->getPlayer(m_activePlayer).addAction(false,MAGICAL_SHIFT);
				m_currentGameState = MAGICAL_SHIFT_STATE;		
				}
				break;
			case MIND_CONTROL:	//18
					Mix_PlayChannel(-1,m_mindControl,0);
					m_prevGameState = m_currentGameState;
					m_lastActingPlayer = m_activePlayer;
					m_gameBoard->getPlayer(m_activePlayer).addAction(false,MIND_CONTROL);
					m_currentGameState = SELECT_A_PLAYER;
					//Mix_PlayChannel(-1,m_playerMove,0);
				break;
			case TELEPORT:		//8
				m_gameBoard->getPlayer(m_activePlayer).addAction(false,TELEPORT);
				
				changeTurn();
				break;
			case START_TILE_ID:	
				m_gameBoard->getPlayer(m_activePlayer).addAction(false,START_TILE_ID);
				changeTurn();
				break;
			case EMPTY_TILE:	
				m_gameBoard->getPlayer(m_activePlayer).addAction(false,EMPTY_TILE);
				changeTurn();
				break;
			case MASTER_KEY:	
				m_gameBoard->getPlayer(m_activePlayer).addAction(false,MASTER_KEY);
				//Mix_PlayChannel(-1,m_playerMove,0);
				changeTurn();
				break;
			case ESCAPE_TILE:	
				m_gameBoard->getPlayer(m_activePlayer).addAction(false,ESCAPE_TILE);
				//Mix_PlayChannel(-1,m_playerMove,0);
				changeTurn();
				break;
			case MAGICAL_HARP:  
				m_gameBoard->getPlayer(m_activePlayer).addAction(false,MAGICAL_HARP);
				//Mix_PlayChannel(-1,m_playerMove,0);
				changeTurn();
				break;
			case STRONG_WIND:	//6
				m_gameBoard->getPlayer(m_activePlayer).addAction(false,STRONG_WIND);
				//Mix_PlayChannel(-1,m_wind,0);
				changeTurn();
				break;
			default:
				//cout << "tile not handled in move clean up flag= : " << playerFlag << endl;
				break;
		}
}
void GameData::draw() {
	// clear screen
	SDL_Rect rect = {0,0,m_buffer->w, m_buffer->h};
	SDL_FillRect(m_buffer,&rect,black);
	
	displayWindowCaption();

	if(m_currentGameState != TITLE_MENU && m_currentGameState != END_GAME_STATISTICS) {
		// Layering order: board bg, board grid, UI, player hand
		m_gameBoard->drawBoardBG(m_buffer,m_boardBG);
		m_gameBoard->drawGameGrid(m_buffer);
		m_gameBoard->drawBoardTiles(m_buffer,m_tileBGs,m_tileIcons,m_mPos);
		if(m_currentGameState == PLACE_TILE) {		
			if(m_isGrabbed) {
				// WARNING NEW CODE drawAlphaRect/drawGrabbedTile
	//			drawAlphaRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,DIM_BOARD_COLOR,DIM_BOARD_ALPHA);	
				drawOverlay();
				drawGrabbedTile();
			}
		}
		if(m_currentGameState == PLACE_FLOATING_TILE){
			drawOverlay();
		}
		else if(isAnyState(MAGICAL_SHIFT_STATE) && m_isGrabbed){
			drawOverlay();
		}
		if(m_currentGameState == CONFIRM_ACTION) {
			SDL_BlitSurface(m_confirmationBox,NULL,m_buffer,&m_confirmationRect);
		}
		drawBottomUI();
		drawTopUI();
		// UI Buttons
		SDL_BlitSurface(m_focusOnActivePlayer, NULL, m_buffer, &m_focusOnActivePlayerRect);
		SDL_BlitSurface(m_endOfTurn, NULL, m_buffer, &m_endOfTurnRect);
		SDL_BlitSurface(m_cancelAction, NULL, m_buffer, &m_cancelActionRect);
		SDL_BlitSurface(m_quitButton,NULL,m_buffer,&m_quitButtonRect);

		if(m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).getHandList().size() > PLAYER_TILE_LIST_DISPLAY_MAX)
			drawScrollArrows();
		drawCurrentState();
		drawMiniMap();
		if(isAnyState(PLAYER_TURN_CHANGE,SELECT_A_PLAYER,CONFIRM_ACTION) || (isAnyState(MAGICAL_SHIFT_STATE) && !m_isGrabbed))
			drawDimBoard();
		// WARNING WHEN MIND CONTROL/MUST SHOW CURRENT PLAYER's HAND if AFTER MOVE_OTHER_PLAYER
		if(isAnyState(MOVE_OTHER_PLAYER)){
			if(m_gameBoard->getPlayer(m_lastActingPlayer).getHandList().size() > 0){
				m_gameBoard->drawPlayerHand(m_lastActingPlayer,m_buffer,m_tileBGs,m_tileIcons);
			}
		}
		else{
			if((m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).getHandList().size() > 0) && isNoneOfState(PLAYER_TURN_CHANGE)){
				m_gameBoard->drawPlayerHand(m_playerIsChosen?m_chosenPlayer:m_activePlayer,m_buffer,m_tileBGs,m_tileIcons);
			}
		}
	}
	if(m_currentGameState == PLAYER_TURN_CHANGE) {
		drawTurnChangeScreen();
	}
	if(m_currentGameState == END_GAME) {
		drawTurnChangeScreen();
	}
	if(m_currentGameState == CHOOSE_ACTION) {
		SDL_BlitSurface(m_chooseAction,NULL,m_buffer,&m_chooseActionRect);
	}
	if(m_currentGameState == SELECT_A_PLAYER) {
		drawChoosePlayer();
	}
	if(m_currentGameState == TITLE_MENU) {
		SDL_Rect pos = {0,0,0,0};
		SDL_BlitSurface(m_startMenuBG,NULL,m_buffer,&pos);
	}
	if(m_currentGameState == END_GAME_STATISTICS) {
		drawEndGameStatistics();
	}
	if(m_currentGameState == PLACE_TILE) {
	// WARNING NEW CODE
		if(m_isGrabbed) {
			SDL_Rect destPos = {m_mPos.getX(),m_mPos.getY(),0,0};
			SDL_Rect sourceSize = {0,0,m_gameBoard->getTileTrueWidth(),m_gameBoard->getTileTrueHeight()};

			SDL_Surface * temp = m_grabbedTile.getTileSurface(m_buffer,m_tileBGs,m_tileIcons,m_gameBoard->m_idArray);

			SDL_Surface * tempResized = zoomSurface
			(temp,TILE_IMAGE_MODIFIER_X,TILE_IMAGE_MODIFIER_Y,0);

			SDL_BlitSurface(tempResized,&sourceSize,m_buffer,&destPos);

			SDL_FreeSurface(temp);
			SDL_FreeSurface(tempResized);
		}
	}
	else if(m_currentGameState == MAGICAL_SHIFT_STATE){
		if(m_isGrabbed) {
			SDL_Rect destPos = {m_mPos.getX(),m_mPos.getY(),0,0};
			SDL_Rect sourceSize = {0,0,m_gameBoard->getTileTrueWidth(),m_gameBoard->getTileTrueHeight()};

			SDL_Surface * temp = m_grabbedTile.getTileSurface(m_buffer,m_tileBGs,m_tileIcons,m_gameBoard->m_idArray);

			SDL_Surface * tempResized = zoomSurface
			(temp,TILE_IMAGE_MODIFIER_X,TILE_IMAGE_MODIFIER_Y,0);

			SDL_BlitSurface(tempResized,&sourceSize,m_buffer,&destPos);

			SDL_FreeSurface(temp);
			SDL_FreeSurface(tempResized);
		}
	}
	if(m_currentGameState == PLACE_FLOATING_TILE){
		SDL_Rect destPos = {m_mPos.getX(),m_mPos.getY(),0,0};
			SDL_Rect sourceSize = {0,0,m_gameBoard->getTileTrueWidth(),m_gameBoard->getTileTrueHeight()};

			SDL_Surface * temp = m_grabbedTile.getTileSurface(m_buffer,m_tileBGs,m_tileIcons,m_gameBoard->m_idArray);

			SDL_Surface * tempResized = zoomSurface
			(temp,TILE_IMAGE_MODIFIER_X,TILE_IMAGE_MODIFIER_Y,0);

			SDL_BlitSurface(tempResized,&sourceSize,m_buffer,&destPos);

			SDL_FreeSurface(temp);
			SDL_FreeSurface(tempResized);
	}
	SDL_Flip(m_buffer);
}

void GameData::handleInput() {
	SDL_Event e;
	while(SDL_PollEvent(&e)) {
		switch(e.type)
		{
		case SDL_KEYDOWN:
			handleKey(e);
			break;
		/* mouse events */
		case SDL_MOUSEMOTION:
			m_mPos.setPos(e.motion.x, e.motion.y);
			break;
		case SDL_MOUSEBUTTONDOWN:
				m_isPressed = true;
				m_isReleased = false;
				m_isGrabbed = false;
				handleMouseDown(e);
			break;
		case SDL_MOUSEBUTTONUP:
			handleMouseUp(e);
			m_isGrabbed = false;
			m_isPressed = false;
			m_isReleased = true;
			break;
		/* window events */
		case SDL_VIDEOEXPOSE:
			SDL_Flip(m_buffer);
			break;
		case SDL_VIDEORESIZE:
			m_buffer = SDL_SetVideoMode(e.resize.w,e.resize.h,32,SDL_HWSURFACE | SDL_RESIZABLE);
			break;
		/* standard states */
		case SDL_QUIT:
			m_running = false;
			/*exit(0);*/
			break;
		}
	}
}

void GameData::release() {
	SDL_FreeSurface(m_btmUI);
	SDL_FreeSurface(m_topUI);
	SDL_FreeSurface(m_scrollUI);
	SDL_FreeSurface(m_buffer);
	SDL_FreeSurface(m_startMenuBG);
	TTF_CloseFont(m_font);

	Mix_FreeMusic(m_gameMusic);
	Mix_FreeMusic(m_titleMusic);
	Mix_FreeMusic(m_endGameMusic1);
	Mix_FreeMusic(m_endGameMusic2);
	Mix_FreeChunk( m_click);
	Mix_FreeChunk( m_drakon);
	Mix_FreeChunk( m_drakonStart);
	Mix_FreeChunk( m_destroy);
	Mix_FreeChunk( m_gainCoin);
	Mix_FreeChunk( m_loseCoin);
	Mix_FreeChunk( m_harp);
	Mix_FreeChunk( m_playerMove);
	Mix_FreeChunk( m_magicalShiftWav);
	Mix_FreeChunk( m_placeTileSound);
	Mix_FreeChunk( m_endTurnWav);
	Mix_FreeChunk( m_teleport);
	Mix_FreeChunk( m_mindControl);
	Mix_FreeChunk( m_rotateStartWav);
	Mix_FreeChunk( m_rotateUpWav);
	Mix_FreeChunk( m_rotateDownWav);
	Mix_FreeChunk( m_masterKey);
	Mix_FreeChunk( m_wind);
	Mix_FreeChunk( m_movePlayer);
	Mix_FreeChunk( m_dropTileInvalidAreaWav);
}

/*--- Game Sub-Functions ---*/
list<Tile> GameData::checkValidRotationOnPosCW(Position pos){
	list<Tile> allRotations;
	list<Tile> validRotations;
	// first rotation
	Tile tileToRotate;

	// rotate 3 tiles (iterate count 3 tiles) and push em in if they give a valid placement
	//count = 0;
	// Push all three rotations
	tileToRotate = m_gameBoard->getGameTiles()[pos.getY()][pos.getX()].getTile();
	tileToRotate.rotateCW();
	allRotations.push_back(tileToRotate);
	tileToRotate.rotateCW();
	allRotations.push_back(tileToRotate);
	tileToRotate.rotateCW();
	allRotations.push_back(tileToRotate);
	
	int i = 0;
	// go thru list and check if any are invalid, if so pop it
	for(list<Tile>::iterator it = allRotations.begin(); it != allRotations.end(); it++){
 		checkValidPlacement2(*it);
		////cout << "tile info for each allRotations. [" << i << "]: ";
		////cout << it->toString() << endl;
		if(m_validPlacement[pos.getY()][pos.getX()]){
			validRotations.push_back(*it);
		}
		i++;
		resetValidPlacementArray();
		
	
	} 
	////cout << "checkValidRotationOnPosCW.size(): "<< validRotations.size() << endl;
	return validRotations;
}

list<Tile> GameData::checkValidRotationOnPosCCW(Position pos){
	list<Tile> allRotations;
	list<Tile> validRotations;
	// first rotation
	Tile tileToRotate;

	// rotate 3 tiles (iterate count 3 tiles) and push em in if they give a valid placement
	// Push all three rotations
	tileToRotate = m_gameBoard->getGameTiles()[pos.getY()][pos.getX()].getTile();
	tileToRotate.rotateCCW();
	allRotations.push_back(tileToRotate);
	tileToRotate.rotateCCW();
	allRotations.push_back(tileToRotate);
	tileToRotate.rotateCCW();
	allRotations.push_back(tileToRotate);
	
	// go thru list and check if any are invalid, if so pop it
	for(list<Tile>::iterator it = allRotations.begin(); it != allRotations.end(); it++){
 		checkValidPlacement2(*it);
		if(m_validPlacement[pos.getY()][pos.getX()]){
			validRotations.push_back(*it);
		}
		
		resetValidPlacementArray();
		
	
	} 
	////cout << "checkValidRotationOnPosCCW.size(): "<< validRotations.size() << endl;
	return validRotations;
}
void GameData::handleMouseDownTitleMenu(SDL_Event a_event){
	if(isWithinRect(m_mPos.getX(),m_mPos.getY(),m_menuScreenStartButton)) {
		Mix_PlayChannel(-1,m_click,0);
		m_prevGameState = m_currentGameState;
		m_currentGameState = PLAYER_TURN_CHANGE;
		if(Mix_PlayingMusic()) Mix_HaltMusic();
		Mix_PlayMusic(m_gameMusic,-1);
	}
	else if(isWithinRect(m_mPos.getX(),m_mPos.getY(),m_menuScreenExitButton)) {
		Mix_PlayChannel(-1,m_click,0);
		m_running = false;
		exit(0);
	}
}
void GameData::handleMouseDownPlayerTurnChange(SDL_Event a_event){
	if(isWithinRect(m_mPos.getX(),m_mPos.getY(),m_changeTurnScreen)) {
		Mix_PlayChannel(-1,m_click,0);
		Position playerPos = m_gameBoard->getPlayer(m_activePlayer).getPosition();
		// if on strong wind during start of turn, move counter = 2 else 1
		if((m_gameBoard->getGameTiles()[playerPos.getY()][playerPos.getX()].getTile().getFlag() == STRONG_WIND)) {
			m_moveCounter = 2;
			m_playerStartedStrongWind = true;
			
		} else {
			m_moveCounter = 1;
			m_playerStartedStrongWind = false;
		}		
		m_prevGameState = m_currentGameState;
		m_currentGameState = CHOOSE_ACTION;
		m_oldGameBoard = m_gameBoard;
		if(m_roundStart == -1){
			m_roundStart = SDL_GetTicks();
		}
		m_gameBoard->getPlayer(m_activePlayer).setStartTimer();
		
	}
}
void GameData::handleMouseDownChooseAction(SDL_Event a_event){
	if(isWithinRect(m_mPos.getX(),m_mPos.getY(),m_chooseActionRect)) {
		Mix_PlayChannel(-1,m_click,0);
		if(m_mPos.getX() <= m_chooseActionRect.x + (m_chooseActionRect.w/2)) {
			if(m_moveCounter == 2){
				/// WARNING Position handling
				if(canMoveTwice(m_gameBoard->getPlayer(m_activePlayer).getPosition())){
					m_prevGameState = m_currentGameState;
					m_currentGameState = MOVE_PLAYER;
				}
			}
			else{
				m_prevGameState = m_currentGameState;
				m_currentGameState = MOVE_PLAYER;
			}
		} else if(m_mPos.getX() > m_chooseActionRect.x + (m_chooseActionRect.w/2)) {
			if(m_playerStartedStrongWind && m_moveCounter < 2){
				// player can't place tiles if he's moved once 
			}
			else{
				if(m_gameBoard->getPlayer(m_activePlayer).getHandList().size() > 0){
				m_prevGameState = m_currentGameState;
				m_currentGameState = PLACE_TILE;
				}
			}
		}
	}
}
void GameData::handleMouseDownConfirmAction(SDL_Event a_event){
	if(isWithinRect(m_mPos.getX(),m_mPos.getY(),m_confirmationRect)) {
		Mix_PlayChannel(-1,m_click,0);
		if(m_mPos.getX() <= m_confirmationRect.x + (m_confirmationRect.w/2)) {
			m_prevGameState = m_currentGameState;
			m_currentGameState = m_nextGameState;
		} else if(m_mPos.getX() > m_confirmationRect.x + (m_confirmationRect.w/2)) {

		}
	}
}
void GameData::handleMouseDownPlaceTile(SDL_Event a_event){
	if(!m_isGrabbed) {
		//Position tempo = convertScreenCoordsToGridPos(m_mPos.getX(),m_mPos.getY());
		int index = getHandlistTileIndex(a_event.button.x,a_event.button.y);
		if(index == -1){ // not in handTile
		}
		else{
			
			list<Tile> playersHand = m_gameBoard->getPlayer(m_activePlayer).getHandList();
			if( index < (int)playersHand.size()){
				m_isGrabbed = true;
				
				// make sure list is within size of player hand
				list<Tile>::iterator it = m_gameBoard->getPlayer(m_activePlayer).getHandList().begin();
	//			cout << "size = "<< m_gameBoard->getPlayer(m_activePlayer).getHandList().size() << endl;
				for(int i = 0; i < index; i++,it++);
	//			cout << "index = "<< index << endl;
				

				m_grabbedTile = *it;
		//		cout << m_grabbedTile.toString() << endl;
				//m_gameBoard->getPlayer(m_activePlayer).getHandList().pop
				m_gameBoard->getPlayer(m_activePlayer).getHandList().erase(it);
				
				m_handTileOffset.w = (Uint16)TILE_BG_WIDTH*(Uint16)HAND_TILE_IMAGE_MODIFIER_X*(Uint16)playersHand.size();
			}

		}
	} else {
		m_grabbedTilePos.setX(m_mPos.getX());
		m_grabbedTilePos.setY(m_mPos.getY());
	}
}
void GameData::handleMouseDownMagicalShift(SDL_Event a_event){
	
		if(!m_isGrabbed) {

			Position tempo = convertScreenCoordsToGridPos(m_mPos.getX(),m_mPos.getY());
	//		cout << toString(m_handTileOffset) << endl;
			if(isWithinRect(Position(m_mPos.getX(),m_mPos.getY()),m_handTileOffset)){
				Mix_PlayChannel(-1,m_click,0);
	//			cout << "Magical shift state down\n" ;
				m_isGrabbed = true;
				// Calculate which tile is being grabbed
				int mouseXPosInHandOffset = m_mPos.getX() - m_handTileOffset.x;
				int numberOfTilesInHand = m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).getHandList().size();

				// calc how wide one tile is in offset
				int handTileWidth = (HAND_TILE_IMAGE_MODIFIER_X*TILE_BG_WIDTH);
		//		cout << a_event.button.x << endl;
		//		cout << handTileWidth;
				int tileIndex = (a_event.button.x / handTileWidth);
	//			cout << "index\n";
				
				if(tileIndex == 0) tileIndex++;

				if(m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).getHandList().size() == 0){
					// DONT DO NETHING
				}
				else if(m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).getHandList().size() == 1){
					Tile lastAvailableTileInHand = m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).getHandList().front();
					m_grabbedTile = lastAvailableTileInHand;
					m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).getHandList().pop_front();
					m_handTileOffset.w = m_handTileOffset.w - handTileWidth;
					
				}
				else{
					list<Tile>::iterator it = m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).getHandList().begin();

					// Walk through Player's hand (of tiles) until you hit the index
					for(int count = 0;count != tileIndex-1;count++) {
						it++;	
					}
					// copy the tile with the given Index to m_grabbedTile
					m_grabbedTile = *it;
					// pop that element out of the hand list
					m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).getHandList().erase(it);
					m_handTileOffset.w = m_handTileOffset.w - handTileWidth;
				}
				/* END: WARNING */ 
				m_grabbedTilePos = Position(m_mPos.getX(),m_mPos.getY());
				//////cout << endl << "Grabbed Tile: " << m_grabbedTile.getName() << endl;
				//////cout << "Position: X[" << m_grabbedTilePos.getX() << "]Y[" << m_grabbedTilePos.getY() << "]" << endl;
			}
		}
	 else {
		m_grabbedTilePos.setX(m_mPos.getX());
		m_grabbedTilePos.setY(m_mPos.getY());
	 }


}
void GameData::handleMouseDownSelectPlayer(SDL_Event a_event){
	Position playerPos = m_gameBoard->getPlayer(m_lastActingPlayer).getPosition();
	int tileFlag = m_gameBoard->getGameTiles()[playerPos.getY()][playerPos.getX()].getTile().getFlag();
	if(isWithinRect(a_event.button.x,a_event.button.y,m_choosePlayerRect)) {
		Mix_PlayChannel(-1,m_click,0);
		if(m_mPos.getX() <= m_choosePlayerRect.x + (m_choosePlayerRect.w/4)) {
			if(m_lastActingPlayer != 0 && m_gameBoard->getPlayer(0).getHandList().size() > 0) {
				m_chosenPlayer = 0;
				m_playerIsChosen = true;
				m_playerIsChosenAgain = false;
			}
		}
		if(a_event.button.x > m_choosePlayerRect.x + ((m_choosePlayerRect.w/4)*1) && a_event.button.x
			< m_choosePlayerRect.x + ((m_choosePlayerRect.w/4)*2)) {
			if(m_lastActingPlayer != 1 && m_gameBoard->getPlayer(1).getHandList().size() > 0) {
				m_chosenPlayer = 1;
				m_playerIsChosen = true;
				m_playerIsChosenAgain = false;
			}
		}
		if(NUMBER_OF_PLAYERS > 2 && m_mPos.getX() > m_choosePlayerRect.x + ((m_choosePlayerRect.w/4)*2) && m_mPos.getX()
			< m_choosePlayerRect.x + ((m_choosePlayerRect.w/4)*3)) {
			if(m_lastActingPlayer != 2 && m_gameBoard->getPlayer(2).getHandList().size() > 0) {
				m_chosenPlayer = 2;
				m_playerIsChosen = true;
				m_playerIsChosenAgain = false;
			}
		}
		if(NUMBER_OF_PLAYERS > 3 &&  m_mPos.getX() > m_choosePlayerRect.x + ((m_choosePlayerRect.w/4)*3) && m_mPos.getX()
			< m_choosePlayerRect.x + m_choosePlayerRect.w) {
			if(m_lastActingPlayer != 3 && m_gameBoard->getPlayer(3).getHandList().size() > 0) {
					m_chosenPlayer = 3;
					m_playerIsChosen = true;
				m_playerIsChosenAgain = false;
			}
		}
	}
}
void GameData::handleMouseDownHandlistArrows(SDL_Event a_event){
	if(m_gameBoard->getPlayer(m_activePlayer).getHandList().size() > PLAYER_TILE_LIST_DISPLAY_MAX) {
	SDL_Rect rect1 = {m_arrowsRect.x,m_arrowsRect.y,m_arrowsRect.w/2,m_arrowsRect.h};
	SDL_Rect rect2 = {(Sint16)PLAYER_TILE_LIST_START_X + (Sint16)((TILE_BG_WIDTH*HAND_TILE_IMAGE_MODIFIER_X)*PLAYER_TILE_LIST_DISPLAY_MAX),
		(int)m_arrowsRect.y,
		(int)m_arrowsRect.w/2,
		(int)m_arrowsRect.h};
	if(isWithinRect(m_mPos.getX(),m_mPos.getY(),rect1)) {
		Mix_PlayChannel(-1,m_click,0);
		list<Tile> tempList;
		tempList = m_gameBoard->getPlayer(m_activePlayer).getHandList();
		tempList.push_back(m_gameBoard->getPlayer(m_activePlayer).getHandList().front());
		tempList.pop_front();
		m_gameBoard->getPlayer(m_activePlayer).setHandList(tempList);
	}
	if(isWithinRect(m_mPos.getX(),m_mPos.getY(),rect2)) {
		Mix_PlayChannel(-1,m_click,0);
		list<Tile> tempList;
		tempList = m_gameBoard->getPlayer(m_activePlayer).getHandList();
		tempList.push_front(m_gameBoard->getPlayer(m_activePlayer).getHandList().back());
		tempList.pop_back();
		m_gameBoard->getPlayer(m_activePlayer).setHandList(tempList);
	}
}
}
void GameData::handleMouseDown(SDL_Event a_event) {
	cout << "Current Game State" << toString(m_currentGameState)<<endl;
	if(a_event.button.button == SDL_BUTTON_LEFT) {
		switch(m_currentGameState){
			case TITLE_MENU:
				handleMouseDownTitleMenu(a_event);
				break;
			case PLAYER_TURN_CHANGE:
				handleMouseDownPlayerTurnChange(a_event);
				break;
			case CHOOSE_ACTION:
				handleMouseDownChooseAction(a_event);
				break;
			case CONFIRM_ACTION:
				handleMouseDownConfirmAction(a_event);
				break;
			case PLACE_TILE:
				handleMouseDownPlaceTile(a_event);
				break;
			case MAGICAL_SHIFT_STATE:
				handleMouseDownMagicalShift(a_event);
				break;
			case SELECT_A_PLAYER:
				handleMouseDownSelectPlayer(a_event);
				break;
		}
		if(isNoneOfState(TITLE_MENU,END_GAME_STATISTICS)) {
			handleMouseDownHandlistArrows(a_event);
		}
		if(isAnyState(END_GAME)) {
			if(isWithinRect(a_event.button.x,a_event.button.y,m_changeTurnScreen)) {
				Mix_PlayChannel(-1,m_click,0);
				m_currentGameState = END_GAME_STATISTICS;
			}
		}
		/* Pressing home will focus on current player */
		if(isNoneOfState(TITLE_MENU,PLAYER_TURN_CHANGE,END_GAME_STATISTICS)) {
			if(isWithinRect(a_event.button.x,a_event.button.y,m_focusOnActivePlayerRect)) {
				Mix_PlayChannel(-1,m_click,0);
				centerCamOnPlayer(m_gameBoard->getPlayer(m_activePlayer));
			}
		}
		/**/
		if(isNoneOfState(TITLE_MENU,PLAYER_TURN_CHANGE,END_GAME_STATISTICS)) {
			if(isWithinRect(a_event.button.x,a_event.button.y,m_endOfTurnRect)) {
				Mix_PlayChannel(-1,m_click,0);
				changeTurn();
			}
		}
		/**/
		if(isNoneOfState(TITLE_MENU,PLAYER_TURN_CHANGE,END_GAME_STATISTICS)) {
			if(isWithinRect(a_event.button.x,a_event.button.y,m_cancelActionRect)) {
				Mix_PlayChannel(-1,m_click,0);
				m_currentGameState = m_prevGameState;
			}
		}
		if(isNoneOfState(TITLE_MENU,PLAYER_TURN_CHANGE,END_GAME_STATISTICS)) {
			if(isWithinRect(a_event.button.x,a_event.button.y,m_quitButtonRect)) {
				Mix_PlayChannel(-1,m_click,0);
				m_running = false;
				exit(0);
			}
		}
	}
}
void GameData::handleMouseUpMovePlayer(SDL_Event a_event){
	Position tempPos = convertScreenCoordsToGridPos(m_mPos.getX(),m_mPos.getY());
	if(m_currentGameState != MOVE_OTHER_PLAYER) {
		if(tempPos.getX() == m_gameBoard->getPlayer(m_activePlayer).getPosition().getX()
			&& tempPos.getY() == m_gameBoard->getPlayer(m_activePlayer).getPosition().getY()-1) {
			if(movePlayerUP(m_activePlayer)) {
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
			} else {
				m_prevGameState = m_currentGameState;
				m_currentGameState = CHOOSE_ACTION;
			}
		}
		else if(tempPos.getX() == m_gameBoard->getPlayer(m_activePlayer).getPosition().getX()
			&& tempPos.getY() == m_gameBoard->getPlayer(m_activePlayer).getPosition().getY()+1) {
			if(movePlayerDOWN(m_activePlayer)) {
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
			} else {
				m_prevGameState = m_currentGameState;
				m_currentGameState = CHOOSE_ACTION;
			}
		}
		else if(tempPos.getY() == m_gameBoard->getPlayer(m_activePlayer).getPosition().getY()
				&& tempPos.getX() == m_gameBoard->getPlayer(m_activePlayer).getPosition().getX()-1) {
			if(movePlayerLEFT(m_activePlayer)) {
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
			} else {
				m_prevGameState = m_currentGameState;
				m_currentGameState = CHOOSE_ACTION;
			}
		}
		else if(tempPos.getY() == m_gameBoard->getPlayer(m_activePlayer).getPosition().getY()
				&& tempPos.getX() == m_gameBoard->getPlayer(m_activePlayer).getPosition().getX()+1) {
			if(movePlayerRIGHT(m_activePlayer)) {
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
			} else {
				m_prevGameState = m_currentGameState;
				m_currentGameState = CHOOSE_ACTION;
			}
		}
	} else {
//		cout << endl << "Else statement";
		if(tempPos.getX() == m_gameBoard->getPlayer(m_chosenPlayer).getPosition().getX()
			&& tempPos.getY() == m_gameBoard->getPlayer(m_chosenPlayer).getPosition().getY()-1) {
	//			cout << endl << "Clicking on tile";
			if(movePlayerUP(m_chosenPlayer)) {
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
//				cout << endl << "Registering movement";
			} else {
				m_prevGameState = m_currentGameState;
				m_currentGameState = CHOOSE_ACTION;
			}
		}
		else if(tempPos.getX() == m_gameBoard->getPlayer(m_chosenPlayer).getPosition().getX()
			&& tempPos.getY() == m_gameBoard->getPlayer(m_chosenPlayer).getPosition().getY()+1) {
			if(movePlayerDOWN(m_chosenPlayer)) {
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
			} else {
				m_prevGameState = m_currentGameState;
				m_currentGameState = CHOOSE_ACTION;
			}
		}
		else if(tempPos.getY() == m_gameBoard->getPlayer(m_chosenPlayer).getPosition().getY()
				&& tempPos.getX() == m_gameBoard->getPlayer(m_chosenPlayer).getPosition().getX()-1) {
			if(movePlayerLEFT(m_chosenPlayer)) {
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
			} else {
				m_prevGameState = m_currentGameState;
				m_currentGameState = CHOOSE_ACTION;
			}
		}
		else if(tempPos.getY() == m_gameBoard->getPlayer(m_chosenPlayer).getPosition().getY()
				&& tempPos.getX() == m_gameBoard->getPlayer(m_chosenPlayer).getPosition().getX()+1) {
			if(movePlayerRIGHT(m_chosenPlayer)) {
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
			} else {
				m_prevGameState = m_currentGameState;
				m_currentGameState = CHOOSE_ACTION;
			}
		}
	}
}
void GameData::handleMouseUpPlaceTile(SDL_Event a_event){
	if(m_isGrabbed) {
			Position temp = convertScreenCoordsToGridPos(m_mPos.getX(),m_mPos.getY());
			checkValidPlacement(m_grabbedTile);

			if(isWithinRect(a_event.button.x,a_event.button.y,m_gridUiRect) && m_validPlacement[temp.getY()][temp.getX()]){
					Mix_PlayChannel(-1,m_placeTileSound,0);
					int grabbedTileFlag = m_grabbedTile.getFlag();
					m_gameBoard->placeTile(m_grabbedTile,Position(temp.getX(),temp.getY()),m_activePlayer); 
					 // WARNING odd place to handle tile ability
					m_gameBoard->givePlayerACard(m_activePlayer);
					if(grabbedTileFlag == ESCAPE_TILE){
						m_gameBoard->getPlayer(m_activePlayer).setPos(temp);
						m_gameBoard->getPlayer(m_activePlayer).addAction(true,ESCAPE_TILE);
						changeTurn();
					}
					else{
						m_prevGameState = m_currentGameState;
						m_gameBoard->getPlayer(m_activePlayer).addAction(true,m_grabbedTile.getFlag());
						m_currentGameState = PLACE_TILE_CLEAN_UP;
					}		
					
			}
			else {
		//		cout << " should push front";
				Mix_PlayChannel(-1,m_dropTileInvalidAreaWav,0);
				m_gameBoard->getPlayer(m_activePlayer).getHandList().push_front(m_grabbedTile);
			}
			resetValidPlacementArray();
			
		}
}
void GameData::handleMouseUpMagicalShift(SDL_Event a_event){
	if(m_isGrabbed) {
			Position temp = convertScreenCoordsToGridPos(m_mPos.getX(),m_mPos.getY());
			checkValidPlacement3(m_grabbedTile);
			if(m_validPlacement[temp.getY()][temp.getX()]) {
				Mix_PlayChannel(-1,m_magicalShiftWav,0);
				Tile tileToGivePlayer = m_gameBoard->getGameTile(temp.getY(),temp.getX());
				m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).getHandList().push_front(tileToGivePlayer);
				m_gameBoard->placeTile(m_grabbedTile,Position(temp.getX(),temp.getY()),m_playerIsChosen?m_chosenPlayer:m_activePlayer); 
				if(m_grabbedTile.getFlag() == ESCAPE_TILE){
					m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).addAffectInfo(m_playerIsChosen?m_chosenPlayer:m_activePlayer,ESCAPE_TILE);
					m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).setPos(temp);
					changeTurn();
				}
				else{
					m_prevGameState = m_currentGameState;
					m_currentGameState = PLACE_TILE_CLEAN_UP;
				}
				m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).addAffectInfo(m_playerIsChosen?m_chosenPlayer:m_activePlayer,MAGICAL_SHIFT);
				
			} else {
				Mix_PlayChannel(-1,m_dropTileInvalidAreaWav,0);
				m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).getHandList().push_front(m_grabbedTile);
			}
			resetValidPlacementArray();
		}
}
void GameData::handleMouseUpPlaceFloatingTile(SDL_Event a_event){
		Position clickedIndexArea = convertScreenCoordsToGridPos(m_mPos.getX(),m_mPos.getY());
		checkValidPlacement(m_grabbedTile);
		if(m_validPlacement[clickedIndexArea.getY()][clickedIndexArea.getX()]){
			m_gameBoard->placeTile(m_grabbedTile,Position(clickedIndexArea.getX(),clickedIndexArea.getY()),m_playerIsChosen?m_chosenPlayer:m_activePlayer);
			for(int i = 0; i < NUMBER_OF_PLAYERS; ++i){
				if(m_gameBoard->getPlayer(i).getPosition().equals(m_grabbedTilePos)){
					m_gameBoard->getPlayer(i).setPos(clickedIndexArea);
					m_gameBoard->getPlayer(i).addAffectInfo(m_playerIsChosen?m_chosenPlayer:m_activePlayer,FLOATING_TILE);

				}
			}
			changeTurn();
		}
}
void GameData::handleMouseUpSelectGametile(SDL_Event a_event){
	
	Player thisPlayer = m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer);
	Position thisPlayersPos = thisPlayer.getPosition();
	int playerCurrentPosTileFlag = m_gameBoard->getGameTiles()[thisPlayersPos.getY()][thisPlayersPos.getX()].getTile().getFlag();

	// check clicked area if it has a tile
	// WARNING UI AND HAND_RECTS ARE IN GRID AREA
	
	Position clickedOnArea = convertScreenCoordsToGridPos(a_event.button.x,a_event.button.y);
	
	if(m_grabbedTile.getFlag() == MOVE_DRAKON){
		if(!m_gameBoard->isThereAPlayerOnGameTile(clickedOnArea)
			&& m_gameBoard->getGameTiles()[clickedOnArea.getY()][clickedOnArea.getX()].hasTile()) {
			m_drakonSummoner = m_playerIsChosen?m_chosenPlayer:m_activePlayer;
			m_gameBoard->summonDrakon(clickedOnArea);
			Mix_PlayChannel(-1,m_drakonStart,0);
			changeTurn();
		}
	}
	else if(m_gameBoard->getGameTiles()[clickedOnArea.getY()][clickedOnArea.getX()].hasTile()){
		if(playerCurrentPosTileFlag == TELEPORT){
			Mix_PlayChannel(-1,m_teleport,0);
			int thisPlayer = m_playerIsChosen?m_chosenPlayer:m_activePlayer;
			m_prevGameState = m_currentGameState;
			m_gameBoard->getPlayer(thisPlayer).setPos(clickedOnArea);
			
			m_gameBoard->getPlayer(thisPlayer).addAffectInfo(thisPlayer,TELEPORT);
			m_currentGameState = m_playerIsChosen?
				MOVE_OTHER_PLAYER_CLEAN_UP:
				MOVE_PLAYER_CLEAN_UP;
		}
		else if(playerCurrentPosTileFlag == ROTATE_TILE){
			list<Tile> tileRotations = checkValidRotationOnPosCW(Position(clickedOnArea.getX(),clickedOnArea.getY()));
			if(tileRotations.size() > 0){
				m_grabbedTilePos = clickedOnArea;
				m_prevGameState = m_currentGameState;
				m_currentGameState = ROTATE_TILE_STATE;
			}
		}
		else if(playerCurrentPosTileFlag == DESTROY_TILE){
			if(!m_gameBoard->isThereAPlayerOnGameTile(clickedOnArea)){
				if(m_gameBoard->getGameTile(clickedOnArea.getY(),clickedOnArea.getX()).getFlag() != START_TILE_ID){
					Mix_PlayChannel(-1,m_destroy,0);
					Position currentPlayerPos = m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).getPosition();
					int thisPlayer = m_playerIsChosen?m_chosenPlayer:m_activePlayer;
					m_gameBoard->getPlayer(m_playerIsChosen?m_chosenPlayer:m_activePlayer).addAffectInfo(thisPlayer,DESTROY_TILE);
					m_gameBoard->removeBoardTileAndPutOnDeck(clickedOnArea);
					changeTurn();
				}
			}
		} 
	}
}
void GameData::handleMouseUp(SDL_Event a_event) {
	//cout << "Current game state" << toString(m_currentGameState) << endl;
	if(isAnyState(MOVE_PLAYER,MOVE_OTHER_PLAYER)) {
		handleMouseUpMovePlayer(a_event);
	}
	/* END: MOVE PLAYER USING MOUSE INSTEAD OF KEYBOARD */ 
	if(m_currentGameState == PLACE_TILE){
		handleMouseUpPlaceTile(a_event);

	}
	else if(m_currentGameState == MAGICAL_SHIFT_STATE){
		
		handleMouseUpMagicalShift(a_event);
	}
	else if(m_currentGameState == PLACE_FLOATING_TILE){
		handleMouseUpPlaceFloatingTile(a_event);
	}
	else if(m_currentGameState == SELECT_GAMETILE){
		handleMouseUpSelectGametile(a_event);
	}
}

void GameData::handleKey(SDL_Event a_event) {
	switch(a_event.key.keysym.sym) {
	case SDLK_ESCAPE: // Escape key
		m_running = false;
		exit(0);
		break;
/* temporary HANDLE SELECT_A_PLAYER */
		/*
	case SDLK_1:{
		if(isAnyState(SELECT_A_PLAYER)){
			if(m_activePlayer != 0)
				stealPlayerRandomTile(m_activePlayer,0);
			//
			//// map chamber
			//Position playerPos = m_gameBoard->getPlayer(m_activePlayer).getPosition();
			//playerPos = Position(playerPos.getY(),playerPos.getX());
			//// if curernt player is on map tile steal a random tile from player 1
			//if(m_gameBoard->getGameTile(playerPos).getFlag() == MAP_TILE){
			//	// shuffle deck of the player to steal
			//	m_gameBoard->shuffleDeck(m_gameBoard->getPlayer(0).getHandList()); // MAGIC NUMBER
			//	// get tileToSteal from that player
			//	if(m_gameBoard->getPlayer(0).getHandList().size() > 0) {
			//		Tile tileToSteal = m_gameBoard->getPlayer(0).getHandList().front();// MAGIC NUMBER 
			//		m_gameBoard->getPlayer(0).getHandList().pop_front();
			//		m_gameBoard->getPlayer(m_activePlayer).getHandList().push_front(tileToSteal);
			//		changeTurn();
			//	}
			//}
		}
				}
		break;
	case SDLK_2:{
		if(isAnyState(SELECT_A_PLAYER)){
			if(m_activePlayer != 1)
				stealPlayerRandomTile(m_activePlayer,1);
			
			//// map chamber
			//Position playerPos = m_gameBoard->getPlayer(m_activePlayer).getPosition();
			//playerPos = Position(playerPos.getY(),playerPos.getX());
			//// if curernt player is on map tile steal a random tile from player 1
			//if(m_gameBoard->getGameTile(playerPos).getFlag() == MAP_TILE){
			//	// shuffle deck of the player to steal
			//	m_gameBoard->shuffleDeck(m_gameBoard->getPlayer(1).getHandList()); // MAGIC NUMBER
			//	// get tileToSteal from that player
			//	if(m_gameBoard->getPlayer(1).getHandList().size() > 0) {
			//		Tile tileToSteal = m_gameBoard->getPlayer(1).getHandList().front();// MAGIC NUMBER 
			//		m_gameBoard->getPlayer(1).getHandList().pop_front();
			//		m_gameBoard->getPlayer(m_activePlayer).getHandList().push_front(tileToSteal);
			//		changeTurn();
			//	}
			//}
		}
				}
		break;
	case SDLK_3:{
		if(isAnyState(SELECT_A_PLAYER)){
			if(m_activePlayer != 2)
				stealPlayerRandomTile(m_activePlayer,2);
			
			//// map chamber
			//Position playerPos = m_gameBoard->getPlayer(m_activePlayer).getPosition();
			//playerPos = Position(playerPos.getY(),playerPos.getX());
			//// if curernt player is on map tile steal a random tile from player 1
			//if(m_gameBoard->getGameTile(playerPos).getFlag() == MAP_TILE){
			//	// shuffle deck of the player to steal
			//	m_gameBoard->shuffleDeck(m_gameBoard->getPlayer(2).getHandList()); // MAGIC NUMBER
			//	// get tileToSteal from that player
			//	if(m_gameBoard->getPlayer(2).getHandList().size() > 0) {
			//		Tile tileToSteal = m_gameBoard->getPlayer(2).getHandList().front();// MAGIC NUMBER 
			//		m_gameBoard->getPlayer(2).getHandList().pop_front();
			//		m_gameBoard->getPlayer(m_activePlayer).getHandList().push_front(tileToSteal);
			//		changeTurn();
			//	}
			//}
		}
				}
		break;
	case SDLK_4:{
		if(isAnyState(SELECT_A_PLAYER)){
			if(m_activePlayer != 3)
				stealPlayerRandomTile(m_activePlayer,3);
			
			
			//// map chamber
			//Position playerPos = m_gameBoard->getPlayer(m_activePlayer).getPosition();
			//playerPos = Position(playerPos.getY(),playerPos.getX());
			//// if curernt player is on map tile steal a random tile from player 1
			//if(m_gameBoard->getGameTile(playerPos).getFlag() == MAP_TILE){
			//	// shuffle deck of the player to steal
			//	m_gameBoard->shuffleDeck(m_gameBoard->getPlayer(3).getHandList()); // MAGIC NUMBER
			//	// get tileToSteal from that player
			//	if(m_gameBoard->getPlayer(3).getHandList().size() > 0) {
			//		Tile tileToSteal = m_gameBoard->getPlayer(3).getHandList().front();// MAGIC NUMBER 
			//		m_gameBoard->getPlayer(3).getHandList().pop_front();
			//		m_gameBoard->getPlayer(m_activePlayer).getHandList().push_front(tileToSteal);
			//		changeTurn();
			//	}
			//}
		}
				}
		break; */ 
/* END: HANDLE SELECT_A_PLAYER */
	// for next 4 cases
		// if player can move into tile he will and change turn to go to player clean up phase
		// else he will have to choose a correct action
	case SDLK_UP:
		if(isAnyState(MOVE_PLAYER)) {		
			if(movePlayerUP(m_activePlayer)) {
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
			}
			else {
				m_prevGameState = m_currentGameState;
				m_currentGameState = CHOOSE_ACTION;
			}
		}
		else if(isAnyState(MOVE_OTHER_PLAYER)){
			if(movePlayerUP(m_chosenPlayer)) {
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
			}
		}
		break;
	case SDLK_RIGHT:
		if(isAnyState(MOVE_PLAYER)) {
			if(movePlayerRIGHT(m_activePlayer)) { 
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
			}
			else {
				m_prevGameState = m_currentGameState;
				m_currentGameState = CHOOSE_ACTION;
			}

		}
		else if(isAnyState(MOVE_OTHER_PLAYER)){
			if(movePlayerRIGHT(m_chosenPlayer)) {
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
			}

		}
		break;
	case SDLK_DOWN:

		if(isAnyState(MOVE_PLAYER)) {
			if(movePlayerDOWN(m_activePlayer)){
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
			}
			else {
				m_prevGameState = m_currentGameState;
				m_currentGameState = CHOOSE_ACTION;
			}
		}
		else if(isAnyState(MOVE_OTHER_PLAYER)){
			if(movePlayerDOWN(m_chosenPlayer)) {
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
			}

		}
		break;
	case SDLK_LEFT:
		if(isAnyState(MOVE_PLAYER)) {
			if(movePlayerLEFT(m_activePlayer)){				
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
			}
			else {
				m_prevGameState = m_currentGameState;
				m_currentGameState = CHOOSE_ACTION;
			}
		}
		else if(isAnyState(MOVE_OTHER_PLAYER)){
			if(movePlayerLEFT(m_chosenPlayer)) {
				Mix_PlayChannel(-1,m_movePlayer,0);
				m_moveCounter--;
			}
		}

		break;
	case SDLK_i:
		if(isNoneOfState(TITLE_MENU))
			moveCamUP();
		break;
	case SDLK_l:
		if(isNoneOfState(TITLE_MENU))
			moveCamRIGHT();
		break;
	case SDLK_k:
		if(isNoneOfState(TITLE_MENU))
			moveCamDOWN();
		break;
	case SDLK_j:
		if(isNoneOfState(TITLE_MENU))
			moveCamLEFT();
		break;
	case SDLK_HOME:
		if(isNoneOfState(TITLE_MENU)){
			centerCamOnPlayer(m_gameBoard->getPlayer(m_activePlayer));
		}
		break;
	case SDLK_PAGEUP:
		if(isAnyState(PLACE_TILE) && m_isGrabbed){
			Mix_PlayChannel(-1,m_rotateUpWav,0);
			m_grabbedTile.rotateCW();
		}
		else if(isAnyState(PLACE_FLOATING_TILE)){
			Mix_PlayChannel(-1,m_rotateUpWav,0);
			m_grabbedTile.rotateCW();
		}
		else if(isAnyState(ROTATE_TILE_STATE)){

			
			list<Tile> tileRotations = checkValidRotationOnPosCW(m_grabbedTilePos);
			if(tileRotations.size() > 0){
				Mix_PlayChannel(-1,m_rotateUpWav,0);
				m_gameBoard->setBoardTile(tileRotations.front(),m_grabbedTilePos.getY(),m_grabbedTilePos.getX(),m_playerIsChosen?m_chosenPlayer:m_activePlayer);
			}

		}
		else if(isAnyState(MAGICAL_SHIFT_STATE) && m_isGrabbed){
			Mix_PlayChannel(-1,m_rotateUpWav,0);
			m_grabbedTile.rotateCW();
		}
		break;
	case SDLK_PAGEDOWN:
		if(isAnyState(PLACE_TILE) && m_isGrabbed){
			Mix_PlayChannel(-1,m_rotateDownWav,0);
			m_grabbedTile.rotateCCW();
		}
		else if(isAnyState(PLACE_FLOATING_TILE)){
			Mix_PlayChannel(-1,m_rotateDownWav,0);
			m_grabbedTile.rotateCCW();
		}
		else if(isAnyState(ROTATE_TILE_STATE)){
			
			list<Tile> tileRotations = checkValidRotationOnPosCCW(m_grabbedTilePos);
			if(tileRotations.size() > 0){
				Mix_PlayChannel(-1,m_rotateDownWav,0);
				m_gameBoard->setBoardTile(tileRotations.front(),m_grabbedTilePos.getY(),m_grabbedTilePos.getX(),m_playerIsChosen?m_chosenPlayer:m_activePlayer);
			}

		}
		else if(isAnyState(MAGICAL_SHIFT_STATE) && m_isGrabbed){
			Mix_PlayChannel(-1,m_rotateDownWav,0);
			m_grabbedTile.rotateCCW();
		}
		break;
	case SDLK_RETURN:
		if(isAnyState(ROTATE_TILE_STATE)){
			Mix_PlayChannel(-1,m_placeTileSound,0); 
			// for each player on the rotated tile (m_grabbedTilePos), addAffect(fromThisPlayer,rotate_tile)
			list<int> playersOnThisTile;
			int thisPlayer = m_playerIsChosen?m_chosenPlayer:m_activePlayer;
			for(int i = 0; i < NUMBER_OF_PLAYERS; i++){
				if(m_gameBoard->getPlayer(i).getPosition().equals(m_grabbedTilePos)){
					playersOnThisTile.push_back(i);
				}
			}
			while(playersOnThisTile.size() > 0){
				m_gameBoard->getPlayer(playersOnThisTile.front()).addAffectInfo(thisPlayer,ROTATE_TILE);
				playersOnThisTile.pop_front();
			}
			changeTurn();
		}
		break;
	case SDLK_BACKSPACE:
		if(isNoneOfState(TITLE_MENU,END_GAME,END_GAME_STATISTICS))
			changeTurn();
		break;
	case SDLK_DELETE:
		m_gameBoard = m_oldGameBoard;
		m_currentGameState = m_prevGameState;
		break;
	case SDLK_g:
		m_gameBoard->getPlayer(m_activePlayer).getCoinSack().addCoin(GV_THREE);
		break;
	case SDLK_w:
		toggleFullscreen();
		break;
	default:
		break;
	}
}

void GameData::drawMiniMap(void) {
	int startX = MINIMAP_START_X, startY = MINIMAP_START_Y;
	int rowMin,rowMax,columnMin,columnMax,row=0,column=0;

	Position tempPos = convertScreenCoordsToGridPos(SCREEN_WIDTH/2,SCREEN_HEIGHT/2);
	m_gameBoard->setGridFocus(tempPos);

	rowMin = m_gameBoard->getGridFocus().getY()-MINIMAP_FOCUS_HEIGHT;
	rowMax = m_gameBoard->getGridFocus().getY()+MINIMAP_FOCUS_HEIGHT;
	columnMin = m_gameBoard->getGridFocus().getX()-MINIMAP_FOCUS_WIDTH;
	columnMax = m_gameBoard->getGridFocus().getX()+MINIMAP_FOCUS_WIDTH;
	
	if(rowMin >= 0) {
	} else {
		rowMin = 0;
	}
	if(rowMax <= BOARD_ARRAY_SIZE-1) {
	} else {
		rowMax = BOARD_ARRAY_SIZE;
	}

	if(columnMin >= 0) {
	} else {
		columnMin = 0;
	}
	if(columnMax <= BOARD_ARRAY_SIZE-1) {
	} else {
		columnMax = BOARD_ARRAY_SIZE;
	}

	for(int r=rowMin; r<rowMax; ++r) {
		for(int c=columnMin; c<columnMax; ++c) {
			SDL_Rect position = {startX+(column*MINIMAP_TILE_WIDTH),startY+(row*MINIMAP_TILE_HEIGHT)
				,MINIMAP_TILE_WIDTH,MINIMAP_TILE_HEIGHT};
			if(!m_gameBoard->getGameTiles()[r][c].hasTile()) {
				SDL_FillRect(m_buffer,&position,MINIMAP_EMPTY_COLOR);
			}
			if(m_gameBoard->getGameTiles()[r][c].hasTile()) {
				SDL_FillRect(m_buffer,&position,MINIMAP_TILE_COLOR);
			}
			if(m_gameBoard->getPlayer(m_activePlayer).getPosition().getX() == c
				&& m_gameBoard->getPlayer(m_activePlayer).getPosition().getY() == r) {
				SDL_FillRect(m_buffer,&position,MINIMAP_PLAYER_COLOR);
			}
			++column;
			if(column >= MINIMAP_FOCUS_WIDTH*2) {
				column = 0;
			}
		}
		++row;
		if(row >= MINIMAP_FOCUS_HEIGHT*2) {
			row = 0;
		}
	}

	// DRAW MINIMAP BORDER :)
	// Left Vertical Border
	SDL_Rect position1 = {startX-MINIMAP_BORDER_THICKNESS,startY-MINIMAP_BORDER_THICKNESS
		,MINIMAP_BORDER_THICKNESS,(MINIMAP_BORDER_THICKNESS*2)+((MINIMAP_FOCUS_HEIGHT*2)*MINIMAP_TILE_HEIGHT)};
	SDL_FillRect(m_buffer,&position1,MINIMAP_BORDER_COLOR);
	// Right Vertical Border
	SDL_Rect position2 = {startX+((MINIMAP_FOCUS_WIDTH*2)*MINIMAP_TILE_WIDTH)
		,startY-MINIMAP_BORDER_THICKNESS
		,MINIMAP_BORDER_THICKNESS,(MINIMAP_BORDER_THICKNESS*2)+((MINIMAP_FOCUS_HEIGHT*2)*MINIMAP_TILE_HEIGHT)};
	SDL_FillRect(m_buffer,&position2,MINIMAP_BORDER_COLOR);
	// Top Horizontal Border
	SDL_Rect position3 = {startX,startY-MINIMAP_BORDER_THICKNESS
		,((MINIMAP_FOCUS_WIDTH*2)*MINIMAP_TILE_WIDTH),MINIMAP_BORDER_THICKNESS};
	SDL_FillRect(m_buffer,&position3,MINIMAP_BORDER_COLOR);
	// Bottom Horizontal Border
	SDL_Rect position4 = {startX,startY+((MINIMAP_FOCUS_HEIGHT*2)*MINIMAP_TILE_HEIGHT)
		,((MINIMAP_FOCUS_WIDTH*2)*MINIMAP_TILE_WIDTH),MINIMAP_BORDER_THICKNESS};
	SDL_FillRect(m_buffer,&position4,MINIMAP_BORDER_COLOR);

	int rowsOnScreen = SCREEN_HEIGHT/((TILE_BG_HEIGHT*TILE_IMAGE_MODIFIER_Y)+GRID_THICK_Y);
	int columnsOnScreen = SCREEN_WIDTH/((TILE_BG_WIDTH*TILE_IMAGE_MODIFIER_X)+GRID_THICK_X);

	// Draw Camera
	// Draw Left Vertical Line
	SDL_Rect pos1 = {(startX+(((MINIMAP_FOCUS_WIDTH*2)*MINIMAP_TILE_WIDTH)/2)-((columnsOnScreen*MINIMAP_TILE_WIDTH)/2))
		,(startY+(((MINIMAP_FOCUS_HEIGHT*2)*MINIMAP_TILE_HEIGHT)/2)-((rowsOnScreen*MINIMAP_TILE_HEIGHT)/2)),
		1,rowsOnScreen*MINIMAP_TILE_HEIGHT};
	SDL_FillRect(m_buffer,&pos1,MINIMAP_CAM_COLOR);
	// Draw Right Vertical Line
	SDL_Rect pos2 = {(startX+(((MINIMAP_FOCUS_WIDTH*2)*MINIMAP_TILE_WIDTH)/2)+(((columnsOnScreen+1)*MINIMAP_TILE_WIDTH)/2))
		,(startY+(((MINIMAP_FOCUS_HEIGHT*2)*MINIMAP_TILE_HEIGHT)/2)-((rowsOnScreen*MINIMAP_TILE_HEIGHT)/2)),
		1,rowsOnScreen*MINIMAP_TILE_HEIGHT};
	SDL_FillRect(m_buffer,&pos2,MINIMAP_CAM_COLOR);
	// Draw Top Horizonal Line
	SDL_Rect pos3 = {(startX+(((MINIMAP_FOCUS_WIDTH*2)*MINIMAP_TILE_WIDTH)/2)-((columnsOnScreen*MINIMAP_TILE_WIDTH)/2))
		,(startY+(((MINIMAP_FOCUS_HEIGHT*2)*MINIMAP_TILE_HEIGHT)/2)-((rowsOnScreen*MINIMAP_TILE_HEIGHT)/2)),
		((columnsOnScreen)*MINIMAP_TILE_WIDTH)+(MINIMAP_TILE_WIDTH/2),1};
	SDL_FillRect(m_buffer,&pos3,MINIMAP_CAM_COLOR);
	// Draw Bottom Horizonal Line
	SDL_Rect pos4 = {(startX+(((MINIMAP_FOCUS_WIDTH*2)*MINIMAP_TILE_WIDTH)/2)-((columnsOnScreen*MINIMAP_TILE_WIDTH)/2))
		,(startY+(((MINIMAP_FOCUS_HEIGHT*2)*MINIMAP_TILE_HEIGHT)/2)+((rowsOnScreen*MINIMAP_TILE_HEIGHT)/2)),
		((columnsOnScreen)*MINIMAP_TILE_WIDTH)+(MINIMAP_TILE_WIDTH/2),1};
	SDL_FillRect(m_buffer,&pos4,MINIMAP_CAM_COLOR);
	if(m_mPos.getX() > startX && m_mPos.getX() < startX + ((MINIMAP_FOCUS_WIDTH*2)*MINIMAP_TILE_WIDTH)) {
		if(m_mPos.getY() > startY && m_mPos.getY() < startY + ((MINIMAP_FOCUS_HEIGHT*2)*MINIMAP_TILE_HEIGHT)) {
			if(m_isPressed && !m_isGrabbed) {
				int tX = m_mPos.getX() - startX;
				int tY = m_mPos.getY() - startY;
				int tR = 0;
				int tC = 0;

				for(int r=0; r<MINIMAP_FOCUS_HEIGHT*2; ++r) {
					for(int c=0; c<MINIMAP_FOCUS_WIDTH*2; ++c) {
						if(tX >= c*MINIMAP_TILE_WIDTH && tX < (c+1)*MINIMAP_TILE_WIDTH) {
							tC = c+columnMin;
						}
					}
					if(tY >= r*MINIMAP_TILE_HEIGHT && tY < (r+1)*MINIMAP_TILE_HEIGHT) {
						tR = r+rowMin;
					}
				}
				m_gameBoard->setGridFocus(Position(tC,tR));
				m_gameBoard->setGridStartPos();
			}
		}
	}
}
void GameData::drawGrabbedTile() {
	if(m_isGrabbed) {
		SDL_Rect destPos = {m_mPos.getX(),m_mPos.getY(),0,0};
		SDL_Rect sourceSize = {0,0,m_gameBoard->getTileTrueWidth(),m_gameBoard->getTileTrueHeight()};

		SDL_Surface * temp = m_grabbedTile.getTileSurface(m_buffer,m_tileBGs,m_tileIcons,m_gameBoard->m_idArray);

		SDL_Surface * tempResized = zoomSurface
		(temp,TILE_IMAGE_MODIFIER_X,TILE_IMAGE_MODIFIER_Y,0);

		SDL_BlitSurface(tempResized,&sourceSize,m_buffer,&destPos);

		SDL_FreeSurface(temp);
		SDL_FreeSurface(tempResized);
	}
}

void GameData::drawTopUI() {
	string t_info;

	for(int i = 0; i < m_totalPlayers; i++)
	{
		t_info += "P";
		t_info += getIntToStr(i+1);
		t_info += ": ";
		//t_info += getIntToStr(m_gameBoard->getPlayer(i).getCoinSack().getGoldTotal());//getIntToStr(m_totalGold[i]);
		t_info += getIntToStr(m_gameBoard->getPlayer(i).getCoinSack().getGoldPieceCount());
		t_info += "gp,    ";

//		t_info.append("P" + i + " Gold: " + m_totalGold[i] + "   ");
	}
	showImage(0,0,m_topUI,m_buffer);
	m_messageUI = TTF_RenderText_Solid(m_font, t_info.c_str(), getColor(orange));
	string pinfo; 
		pinfo += "P"; 
		pinfo += getIntToStr(m_activePlayer+1) ;
		pinfo += " turn.";
	
	string paction;
		paction += "P";
		//paction += getIntToStr(m_lastActingPlayer+1) ;
		paction += getIntToStr(m_chosenPlayer+1) ;
		paction += "'s Control!.";

		SDL_Color playerColor = {0,0,0,0};
	switch(m_chosenPlayer){
		case 0: playerColor = getColor(lightgreen);		break;
		case 1: playerColor = getColor(lightred);		break;
		case 2: playerColor = getColor(lightyellow);	break;
		case 3: playerColor = getColor(lightblue);		break;
		default: 
			playerColor = getColor(white);		break;
	}
	SDL_Surface * currentPlayerText = TTF_RenderText_Solid(m_font, pinfo.c_str(), playerColor);
	SDL_Surface * currentPlayerText2;
	showImage(m_buffer->w - m_messageUI->w, 10, m_messageUI, m_buffer);
	showImage(m_buffer->w/5-currentPlayerText->w/2, 10, currentPlayerText, m_buffer);
//	if(isNoneOfState(SELECT_A_PLAYER,MOVE_PLAYER) && m_playerIsChosen){
	if((m_currentGameState == SELECT_GAMETILE || m_currentGameState ==  MAGICAL_SHIFT_STATE || m_currentGameState == ROTATE_TILE_STATE) && m_playerIsChosen){
		switch(m_lastActingPlayer){
			case 0: playerColor = getColor(lightgreen);		break;
			case 1: playerColor = getColor(lightred);		break;
			case 2: playerColor = getColor(lightyellow);	break;
			case 3: playerColor = getColor(lightblue);		break;
			default: 
				playerColor = getColor(white);		break;
		}
		currentPlayerText2 = TTF_RenderText_Solid(m_font, paction.c_str(), playerColor);
		showImage(m_buffer->w/5-currentPlayerText2->w/2, 40, currentPlayerText2, m_buffer);
	}
	else if(m_currentGameState == MOVE_OTHER_PLAYER){
		paction = "P";
		//paction += getIntToStr(m_lastActingPlayer+1) ;
		paction += getIntToStr(m_lastActingPlayer+1) ;
		paction += "'s Controling P";
		paction += getIntToStr(m_chosenPlayer+1) ;
		paction += "!.";
		if(m_playerIsChosen){
			switch(m_lastActingPlayer){
				case 0: playerColor = getColor(lightgreen);		break;
				case 1: playerColor = getColor(lightred);		break;
				case 2: playerColor = getColor(lightyellow);	break;
				case 3: playerColor = getColor(lightblue);		break;
				default: 
					playerColor = getColor(white);		break;
			}
		}
		currentPlayerText2 = TTF_RenderText_Solid(m_font, paction.c_str(), playerColor);
		showImage(m_buffer->w/5-currentPlayerText2->w/2, 40, currentPlayerText2, m_buffer);
	}
	else if(m_currentGameState == SELECT_A_PLAYER && m_playerIsChosen){
		paction = "P";
		//paction += getIntToStr(m_lastActingPlayer+1) ;
		paction += getIntToStr(m_lastActingPlayer+1) ;
		paction += "choose a Player";
		//paction += getIntToStr(m_chosenPlayer+1) ;
		paction += "!.";

		switch(m_lastActingPlayer){
			case 0: playerColor = getColor(lightgreen);		break;
			case 1: playerColor = getColor(lightred);		break;
			case 2: playerColor = getColor(lightyellow);	break;
			case 3: playerColor = getColor(lightblue);		break;
			default: 
				playerColor = getColor(white);		break;
		}
		currentPlayerText2 = TTF_RenderText_Solid(m_font, paction.c_str(), playerColor);
		showImage(m_buffer->w/5-currentPlayerText2->w/2, 40, currentPlayerText2, m_buffer);
	}
}

void GameData::drawBottomUI()
{
	showImage(m_bottomUiRect.x,m_bottomUiRect.y,m_btmUI,m_buffer);
	//SDL_SetAlpha(m_scrollUI, SDL_SRCALPHA, m_alpha);
	showImage(10,m_buffer->h - (m_scrollUI->h+5),m_scrollUI,m_buffer);
}

void GameData::drawCurrentState() {
	SDL_FillRect(m_buffer,&m_gameStatePos,brown);

	string state;
	state += toString(m_currentGameState);
	SDL_Surface * gameStateSurface = TTF_RenderText_Solid(m_font2small,state.c_str(),getColor(green));
	showImage(m_gameStatePos.x+m_gameStatePos.w/2-gameStateSurface->w/2,m_gameStatePos.y+1,gameStateSurface,m_buffer);
}
void GameData::drawTurnChangeScreen(void) {
	SDL_FillRect(m_buffer,&m_changeTurnScreen,brown);

	if(m_currentGameState != END_GAME) {
		string t_title;
		t_title += "Player ";
		t_title += getIntToStr(m_activePlayer+1);
		t_title += "'s Turn";
		SDL_Surface * m_messageChangeTurn = TTF_RenderText_Solid(m_font2,t_title.c_str(),getColor(black));
		showImage(m_changeTurnScreen.x+120,m_changeTurnScreen.y+10,m_messageChangeTurn,m_buffer);

		string t_info;
		t_info += "Gold Pieces: ";
		t_info += getIntToStr(m_totalGold[m_activePlayer]);
		t_info += "gp";
		SDL_Surface * m_messageChangeTurn2 = TTF_RenderText_Solid(m_font2small,t_info.c_str(),getColor(black));
		showImage(m_changeTurnScreen.x+100,m_changeTurnScreen.y+100,m_messageChangeTurn2,m_buffer);

		string t_info2;
		t_info2 += "# of Tiles: ";
		t_info2 += getIntToStr(m_gameBoard->getPlayer(m_activePlayer).getHandList().size());
		t_info2 += " tiles";
		SDL_Surface * m_messageChangeTurn3 = TTF_RenderText_Solid(m_font2small,t_info2.c_str(),getColor(black));
		showImage(m_changeTurnScreen.x+100,m_changeTurnScreen.y+140,m_messageChangeTurn3,m_buffer);

		string t_continue;
		t_continue += "Click to continue...";
		SDL_Surface * m_messageChangeTurn4 = TTF_RenderText_Solid(m_font2small,t_continue.c_str(),getColor(black));
		showImage(m_changeTurnScreen.x+100,m_changeTurnScreen.y+260,m_messageChangeTurn4,m_buffer);
	} else {
		string t_title2;
		t_title2 += "GAME OVER";
		SDL_Surface * m_messageChangeTurn5 = TTF_RenderText_Solid(m_font2,t_title2.c_str(),getColor(black));
		showImage(m_changeTurnScreen.x+50,m_changeTurnScreen.y+10,m_messageChangeTurn5,m_buffer);

		int winner = 0;
		for(int i = 0; i < NUMBER_OF_PLAYERS; i++){
			if(m_gameBoard->getPlayer(i).getCoinSack().getGoldTotal() >= 10){
				winner = i;
			}
		}

		string t_info3;
		t_info3 += "Player ";
		t_info3 += getIntToStr(winner+1);
		t_info3 += " Won!";
		SDL_Surface * m_messageChangeTurn6 = TTF_RenderText_Solid(m_font2small,t_info3.c_str(),getColor(black));
		showImage(m_changeTurnScreen.x+150,m_changeTurnScreen.y+150,m_messageChangeTurn6,m_buffer);

		string t_continue2;
		t_continue2 += "Click to continue...";
		SDL_Surface * m_messageChangeTurn7 = TTF_RenderText_Solid(m_font2small,t_continue2.c_str(),getColor(black));
		showImage(m_changeTurnScreen.x+150,m_changeTurnScreen.y+260,m_messageChangeTurn7,m_buffer);
	}
}

void GameData::drawDimBoard(void) {
	SDL_Surface * tempCopySurface = SDL_ConvertSurface(m_buffer, m_buffer->format, SDL_SWSURFACE);
	SDL_Rect tempRect = {0,0,SCREEN_WIDTH,SCREEN_HEIGHT};
	SDL_Rect destRect = {0,0,0,0};
	
	SDL_FillRect(tempCopySurface,&tempRect,DIM_BOARD_COLOR);
	SDL_SetAlpha(tempCopySurface,SDL_SRCALPHA,DIM_BOARD_ALPHA);

	SDL_BlitSurface(tempCopySurface,NULL,m_buffer,&destRect);
	SDL_FreeSurface(tempCopySurface);
}
void GameData::drawChoosePlayer(void) {
	SDL_BlitSurface(m_choosePlayerPic,NULL,m_buffer,&m_choosePlayerRect);

	//blit(X_Pic,m_buffer,m_choosePlayerRect.x+10,m_choosePlayerRect.y+32);
	//switch(m_playerIsChosen?m_lastActingPlayer:m_activePlayer) {
	switch(m_activePlayer) {
		case 0: {
				SDL_Rect destRect = {m_choosePlayerRect.x+10,m_choosePlayerRect.y+32,0,0};
				SDL_BlitSurface(X_Pic,NULL,m_buffer,&destRect);
			}
			break;
		case 1: {
				SDL_Rect destRect = {m_choosePlayerRect.x+((m_choosePlayerRect.w/4)*1)+10,m_choosePlayerRect.y+32,0,0};
				SDL_BlitSurface(X_Pic,NULL,m_buffer,&destRect);
			}
			break;
		case 2: {
				SDL_Rect destRect = {m_choosePlayerRect.x+((m_choosePlayerRect.w/4)*2)+10,m_choosePlayerRect.y+32,0,0};
				SDL_BlitSurface(X_Pic,NULL,m_buffer,&destRect);
			}
			break;
		case 3: {
				SDL_Rect destRect = {m_choosePlayerRect.x+((m_choosePlayerRect.w/4)*3)+10,m_choosePlayerRect.y+32,0,0};
				SDL_BlitSurface(X_Pic,NULL,m_buffer,&destRect);
			}
			break;
		default:
			cout << endl << "ERROR! m_activePlayer undefined...(void drawChoosePlayer(void))" << endl;
			break;
	}
	/*
	if(m_gameBoard->getPlayer(0).getHandList().size() == 0) {
		blit(X_Pic,m_buffer,m_choosePlayerRect.x+10,m_choosePlayerRect.y+32);
	}
	if(m_gameBoard->getPlayer(1).getHandList().size() == 0) {
		blit(X_Pic,m_buffer,m_choosePlayerRect.x+((m_choosePlayerRect.w/4)*1)+10,m_choosePlayerRect.y+32);
	}
	if(m_gameBoard->getPlayer(2).getHandList().size() == 0 || NUMBER_OF_PLAYERS < 2) { 
		blit(X_Pic,m_buffer,m_choosePlayerRect.x+((m_choosePlayerRect.w/4)*2)+10,m_choosePlayerRect.y+32);
	}
	if(m_gameBoard->getPlayer(3).getHandList().size() == 0 || NUMBER_OF_PLAYERS < 3) {
		blit(X_Pic,m_buffer,m_choosePlayerRect.x+((m_choosePlayerRect.w/4)*3)+10,m_choosePlayerRect.y+32);
	}
	*/ 
}
void GameData::drawAlphaRect(int xPos,int yPos,int width,int height,Uint32 col,int alpha) {
	SDL_Surface * tempCopySurface = SDL_ConvertSurface(m_buffer, m_buffer->format, SDL_HWSURFACE);
	SDL_Rect tempRect = {xPos,yPos,width,height};
	SDL_Rect destRect = {0,0,0,0};
	
	SDL_FillRect(tempCopySurface,&tempRect,col);
	SDL_SetAlpha(tempCopySurface,SDL_SRCALPHA,alpha);

	SDL_BlitSurface(tempCopySurface,NULL,m_buffer,&destRect);
	SDL_FreeSurface(tempCopySurface);
}
void GameData::drawScrollArrows(void) {
	SDL_Surface * tempCopySurface = SDL_ConvertSurface(m_buffer, m_buffer->format, SDL_SWSURFACE);
	SDL_Rect destRect = {m_arrowsRect.x,m_arrowsRect.y,0,0};
	SDL_Rect rect1 = {0,0,m_arrowsRect.w/2,m_arrowsRect.h};

	SDL_BlitSurface(m_arrowsPic,&rect1,tempCopySurface,&destRect);

	destRect.x = PLAYER_TILE_LIST_START_X + (Sint16)((TILE_BG_WIDTH*HAND_TILE_IMAGE_MODIFIER_X)*PLAYER_TILE_LIST_DISPLAY_MAX);
	rect1.x = m_arrowsRect.w/2;

	SDL_BlitSurface(m_arrowsPic,&rect1,tempCopySurface,&destRect);

	SDL_SetAlpha(tempCopySurface,SDL_SRCALPHA,SCROLL_ARROWS_ALPHA);

	destRect.x = 0;
	destRect.y = 0;

	SDL_BlitSurface(tempCopySurface,NULL,m_buffer,&destRect);
	SDL_FreeSurface(tempCopySurface);
}
void GameData::drawEndGameStatistics(void) {
	int nextLine = 80;

	SDL_Rect background = {0,0,SCREEN_WIDTH,SCREEN_HEIGHT};
	SDL_FillRect(m_buffer,&background,white);
	showImage(m_buffer->w/2 -m_endGameBG->w/2,20,m_endGameBG,m_buffer);

	string title;
	title += "Post-Game Review";
	SDL_Surface * m_messageEndTitle = TTF_RenderText_Solid(m_font2,title.c_str(),getColor(black));
	showImage(400,15,m_messageEndTitle,m_buffer);
	SDL_FreeSurface(m_messageEndTitle);

	string header; string header1;
	header += "| Time Elapsed |               ";
	header += " | Average Round Time |";
	header1 += "Rounds Completed | ";
	header1 += "Drakon Summoner";
	SDL_Surface * m_messageEndHeader = TTF_RenderText_Solid(m_font2small,header.c_str(),getColor(black));
	showImage(275,nextLine,m_messageEndHeader,m_buffer);
	SDL_FreeSurface(m_messageEndHeader);

	nextLine += 40;

	Uint32 totalTime = 0;
	Uint32 avgRoundTime = 0;
	list<Uint32>::iterator avgRoundTimeIter;
	for(avgRoundTimeIter = m_timeTakenEachRoundList.begin(); avgRoundTimeIter != m_timeTakenEachRoundList.end(); ++avgRoundTimeIter) {
		totalTime += *avgRoundTimeIter;
	}
	if(m_roundsCompleted > 0) {
		avgRoundTime = totalTime/m_timeTakenEachRoundList.size();
	} else {
		avgRoundTime = totalTime;
	}

	string header2, header2a;
	header2 += "      ";
	header2 += getIntToStr((int)totalTime/1000);
	header2 += "s                                            ";
	header2 += getIntToStr((int)avgRoundTime/1000);
	header2 += "s";
	SDL_Surface * m_messageEndHeader2 = TTF_RenderText_Solid(m_font2small,header2.c_str(),getColor(blue));
	showImage(320,nextLine,m_messageEndHeader2,m_buffer);
	SDL_FreeSurface(m_messageEndHeader2);
	
	nextLine += 50;

	SDL_Surface * m_messageEndHeader1 = TTF_RenderText_Solid(m_font2small,header1.c_str(),getColor(black));
	showImage(275,nextLine,m_messageEndHeader1,m_buffer);
	SDL_FreeSurface(m_messageEndHeader1);

	header2a += getIntToStr(m_roundsCompleted);
	header2a += "                                     Player ";
	if(m_drakonSummoner >= 0 && m_drakonSummoner <= NUMBER_OF_PLAYERS) {
		header2a += getIntToStr(m_drakonSummoner);
	} else {
		header2a += "N/A";
	}

	nextLine += 50;

	SDL_Surface * m_messageEndHeader2a = TTF_RenderText_Solid(m_font2small,header2a.c_str(),getColor(blue));
	showImage(360,nextLine,m_messageEndHeader2a,m_buffer);
	SDL_FreeSurface(m_messageEndHeader2a);

	nextLine += 50;

	for(int i=0; i<NUMBER_OF_PLAYERS; ++i) {
		string playerHeader;
		playerHeader += "Player|";
		playerHeader += "Gold Pieces|";
		playerHeader += "Total Value|";
		playerHeader += "Gold Lost|";
		playerHeader += "Gold Received|";
		SDL_Surface * m_messagePlayerHeader = TTF_RenderText_Solid(m_font3,playerHeader.c_str(),getColor(black));
		showImage(275,nextLine,m_messagePlayerHeader,m_buffer);
		SDL_FreeSurface(m_messagePlayerHeader);
		
		nextLine += 50;

		string playerHeader2;
		playerHeader2 += "  ";
		playerHeader2 += getIntToStr(i+1);
		playerHeader2 += "             ";
		playerHeader2 += getIntToStr(m_gameBoard->getPlayer(i).getCoinSack().getGoldPieceCount());
		playerHeader2 += "                    ";
		playerHeader2 += getIntToStr(m_gameBoard->getPlayer(i).getCoinSack().getGoldTotal());
		playerHeader2 += "                  ";
		playerHeader2 += getIntToStr(m_gameBoard->getPlayer(i).getCoinSack().getTotalGoldLost());
		playerHeader2 += "                     ";
		playerHeader2 += getIntToStr(m_gameBoard->getPlayer(i).getCoinSack().getTotalGoldReceived());
		SDL_Surface * m_messagePlayerHeader2 = TTF_RenderText_Solid(m_font3,playerHeader2.c_str(),getColor(blue));
		showImage(275,nextLine,m_messagePlayerHeader2,m_buffer);
		SDL_FreeSurface(m_messagePlayerHeader2);

		nextLine += 50;
	}
}
void GameData::showImage(int a_x, int a_y, SDL_Surface *a_source, SDL_Surface *a_destination) {
	SDL_Rect offset; // holds x and y
	offset.x = a_x;
	offset.y = a_y;

	SDL_BlitSurface(a_source, NULL, a_destination, &offset);
}

void GameData::changeTurn() {
	Mix_PlayChannel(-1,m_endTurnWav,0);
	m_moveSoundPlayed = false;
	updateDrakonTerror();
	m_gameBoard->getPlayer(m_activePlayer).incTurnsCompleted();
	m_gameBoard->getPlayer(m_activePlayer).setEndTimer();
	m_lastActingPlayer = m_activePlayer;
	m_activePlayer = 1 + m_activePlayer;
	if(m_activePlayer == NUMBER_OF_PLAYERS) {	
		m_activePlayer = 0;
		m_roundsCompleted++;
//		cout << "Round " << m_roundsCompleted<< " FIGHT!\n";
		m_roundEnd = SDL_GetTicks();
		m_timeTakenEachRoundList.push_back(m_roundEnd - m_roundStart);
	}

	m_gameBoard->changeTurn();
	m_prevGameState = m_currentGameState;
	m_currentGameState = PLAYER_TURN_CHANGE;
	m_playerIsChosen = false;
	m_chosenPlayer = -1;
	m_playerIsChosenAgain = false;
	m_isGrabbed = false;
	m_moveCounter = 0;
	m_playerStartedStrongWind = false;
	m_grabbedTile = Tile();

	// check if end game
	for(int i = 0; i < NUMBER_OF_PLAYERS; i++){
		if(m_gameBoard->getPlayer(i).getCoinSack().getGoldTotal() >= 10){
			if(Mix_PlayingMusic()) Mix_HaltMusic();
				Mix_PlayMusic(m_endGameMusic1,-1);
			m_currentGameState = END_GAME;
		}
	}
}

void GameData::stealPlayerRandomTile(int stealer,int stealee) {
	// map chamber
	Position playerPos = m_gameBoard->getPlayer(stealer).getPosition();
	playerPos = Position(playerPos.getY(),playerPos.getX());

	if(m_gameBoard->getPlayer(stealee).getHandList().size() > 0) {
		// if curernt player is on map tile steal a random tile from player 1
		if(m_gameBoard->getGameTile(playerPos).getFlag() == MAP_TILE){
			// shuffle the player's hand list so that we can easily get the front and pop it out of their hand
			m_gameBoard->shuffleDeck(m_gameBoard->getPlayer(stealee).getHandList()); // MAGIC NUMBER
			Tile tileToSteal = m_gameBoard->getPlayer(stealee).getHandList().front();// MAGIC NUMBER 
			m_gameBoard->getPlayer(stealee).getHandList().pop_front();
			m_gameBoard->getPlayer(stealer).getHandList().push_front(tileToSteal);
		}
	}
}
void GameData::resetValidPlacementArray(void) {
	for(int r = 0; r < BOARD_ARRAY_SIZE; ++r) {
		for(int c = 0; c < BOARD_ARRAY_SIZE; ++c) {
			m_validPlacement[r][c] = false;
		} 
	}
}
// Return TRUE if exit is clear, return FALSE if not
// Compares 2 tiles
bool GameData::isExitClear(int r_1, int c_1, arrowDirection direction_1, 
										int r_2, int c_2, arrowDirection direction_2) {
	if(m_gameBoard->getGameTiles()[r_2][c_2].hasTile()) {
		if(m_gameBoard->getGameTile(r_1,c_1).hasExit(direction_1) != m_gameBoard->getGameTile(r_2,c_2).hasExit(direction_2)) {
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
}

void GameData::displayWindowCaption(void) {
	stringstream caption;
	caption << "Drakon Ultimate v0xcccccccc";
	SDL_WM_SetCaption(caption.str().c_str(), NULL);

	//stringstream caption;

	//caption << "Mouse: (" << m_mPos.getX() << "," << m_mPos.getY() << ") | "
	//		<< "grabbed:" << m_isGrabbed << " | "
	//		<< "pressed: " << m_isPressed << " | "
	//		<< "released: " << m_isReleased << " | "
	//		<< "Tile: (" << m_test.x << "," << m_test.y << ")";
	//SDL_WM_SetCaption(caption.str().c_str(), NULL);
}

// UTILIZED BY checkValidPlacment(Tile)
bool GameData::hasNeighbor(Position columnRow, arrowDirection dir){
	if(dir == UP){
		if(columnRow.getY() > 1){
			if(m_gameBoard->getGameTiles()[columnRow.getY()-1][columnRow.getX()].hasTile())
				return true;
		}
	}
	else if(dir == DOWN){
		if(columnRow.getY() < BOARD_ARRAY_SIZE){
			if(m_gameBoard->getGameTiles()[columnRow.getY()+1][columnRow.getX()].hasTile())
				return true;
		}
	}
	else if(dir == LEFT){
		if(columnRow.getX() > 1){
			if(m_gameBoard->getGameTiles()[columnRow.getY()][columnRow.getX()-1].hasTile())
				return true;
		}
	}
	else if(dir == RIGHT){
		if(columnRow.getX() < BOARD_ARRAY_SIZE){
			if(m_gameBoard->getGameTiles()[columnRow.getY()][columnRow.getX()+1].hasTile())
				return true;
		}
	}	
	return false;
}
bool GameData::hasNeighbor(int r, int c) {
	//bool hasANeighbor = false;
	//if(hasNeighbor(Position(r,c),UP)) hasANeighbor = true;
	//else if(hasNeighbor(Position(r,c),DOWN)) hasANeighbor = true;
	//else if(hasNeighbor(Position(r,c),LEFT))hasANeighbor = true;
	//else if(hasNeighbor(Position(r,c),RIGHT))hasANeighbor = true;
	//return hasANeighbor;
	if(isMiddle(r,c)) {
		if(isNeighborUP(r,c) || isNeighborRIGHT(r,c) || isNeighborDOWN(r,c) || isNeighborLEFT(r,c)) {
			return true;
		} else {
			return false;
		}
	} else if(isTopLeft(r,c)) {
		if(isNeighborRIGHT(r,c) || isNeighborDOWN(r,c)) {
			return true;
		} else {
			return false;
		}
	} else if(isTopRight(r,c)) {
		if(isNeighborLEFT(r,c) || isNeighborDOWN(r,c)) {
			return true;
		} else {
			return false;
		}
	} else if(isBottomLeft(r,c)) {
		if(isNeighborRIGHT(r,c) || isNeighborUP(r,c)) {
			return true;
		} else {
			return false;
		}
	} else if(isBottomRight(r,c)) {
		if(isNeighborLEFT(r,c) || isNeighborUP(r,c)) {
			return true;
		} else {
			return false;
		}
	} else if(isTopEdge(r,c)) {
		if(isNeighborLEFT(r,c) || isNeighborRIGHT(r,c) || isNeighborDOWN(r,c)) {
			return true;
		} else {
			return false;
		}
	} else if(isRightEdge(r,c)) {
		if(isNeighborLEFT(r,c) || isNeighborUP(r,c) || isNeighborDOWN(r,c)) {
			return true;
		} else {
			return false;
		}
	} else if(isBottomEdge(r,c)) {
		if(isNeighborLEFT(r,c) || isNeighborRIGHT(r,c) || isNeighborUP(r,c)) {
			return true;
		} else {
			return false;
		}
	} else if(isLeftEdge(r,c)) {
		if(isNeighborUP(r,c) || isNeighborRIGHT(r,c) || isNeighborDOWN(r,c)) {
			return true;
		} else {
			return false;
		}
	}
	else{
		return false;
	}
}

void GameData::getNeighbors(bool *neighbors,int r, int c) {
	int Up = 0, Right = 1, Down = 2, Left = 3;
	
	if(isMiddle(r,c)) {
		if(isNeighborUP(r,c)) {
			neighbors[Up] = true;
		}
		if(isNeighborRIGHT(r,c)) {
			neighbors[Right] = true;
		}
		if(isNeighborDOWN(r,c)) {
			neighbors[Down] = true;
		}
		if(isNeighborLEFT(r,c)) {
			neighbors[Left] = true;
		}
	} else if(isTopLeft(r,c)) {
		if(isNeighborRIGHT(r,c)) {
			neighbors[Right] = true;
		}
		if(isNeighborDOWN(r,c)) {
			neighbors[Down] = true;
		}
	} else if(isTopRight(r,c)) {
		if(isNeighborLEFT(r,c)) {
			neighbors[Left] = true;
		}
		if(isNeighborDOWN(r,c)) {
			neighbors[Down] = true;
		}
	} else if(isBottomLeft(r,c)) {
		if(isNeighborRIGHT(r,c)) {
			neighbors[Right] = true;
		}
		if(isNeighborUP(r,c)) {
			neighbors[Up] = true;
		}
	} else if(isBottomRight(r,c)) {
		if(isNeighborLEFT(r,c)) {
			neighbors[Left] = true;
		}
		if(isNeighborUP(r,c)) {
			neighbors[Up] = true;
		}
	} else if(isTopEdge(r,c)) {
		if(isNeighborLEFT(r,c)) {
			neighbors[Left] = true;
		}
		if(isNeighborRIGHT(r,c)) {
			neighbors[Right] = true;
		}
		if(isNeighborDOWN(r,c)) {
			neighbors[Down] = true;
		}
	} else if(isRightEdge(r,c)) {
		if(isNeighborLEFT(r,c)) {
			neighbors[Left] = true;
		}
		if(isNeighborUP(r,c)) {
			neighbors[Up] = true;
		}
		if(isNeighborDOWN(r,c)) {
			neighbors[Down] = true;
		}
	} else if(isBottomEdge(r,c)) {
		if(isNeighborLEFT(r,c)) {
			neighbors[Left] = true;
		}
		if(isNeighborRIGHT(r,c)) {
			neighbors[Right] = true;
		}
		if(isNeighborUP(r,c)) {
			neighbors[Up] = true;
		}
	} else if(isLeftEdge(r,c)) {
		if(isNeighborUP(r,c)) {
			neighbors[Up] = true;
		}
		if(isNeighborRIGHT(r,c)) {
			neighbors[Right] = true;
		}
		if(isNeighborDOWN(r,c)) {
			neighbors[Down] = true;
		}
	}
}

bool GameData::isNeighborUP(int r, int c) {
	return m_gameBoard->getGameTiles()[r-1][c].hasTile();
}
bool GameData::isNeighborRIGHT(int r, int c) {
	return m_gameBoard->getGameTiles()[r][c+1].hasTile();
}
bool GameData::isNeighborDOWN(int r, int c) {
	return m_gameBoard->getGameTiles()[r+1][c].hasTile();
}
bool GameData::isNeighborLEFT(int r, int c) {
	return m_gameBoard->getGameTiles()[r][c-1].hasTile();
}

bool GameData::isMiddle(int r, int c) {
	if(r > 0 && c > 0 && r < BOARD_ARRAY_SIZE-1 && c < BOARD_ARRAY_SIZE-1) {
		return true;
	} else {
		return false;
	}
}
bool GameData::isTopLeft(int r, int c) {
	if(r == 0 && c == 0) {
		return true;
	} else {
		return false;
	}
}
bool GameData::isTopRight(int r, int c) {
	if(r == 0 && c == BOARD_ARRAY_SIZE-1) {
		return true;
	} else {
		return false;
	}
}
bool GameData::isBottomLeft(int r, int c) {
	if(r == BOARD_ARRAY_SIZE-1 && c == 0) {
		return true;
	} else {
		return false;
	}
}
bool GameData::isBottomRight(int r, int c) {
	if(r == BOARD_ARRAY_SIZE-1 && c == BOARD_ARRAY_SIZE-1) {
		return true;
	} else {
		return false;
	}
}
bool GameData::isTopEdge(int r, int c) {
	if(r == 0) {
		return true;
	} else {
		return false;
	}
}
bool GameData::isRightEdge(int r, int c) {
	if(c == BOARD_ARRAY_SIZE-1) {
		return true;
	} else {
		return false;
	}
}
bool GameData::isBottomEdge(int r, int c) {
	if(r == BOARD_ARRAY_SIZE-1) {
		return true;
	} else {
		return false;
	}
}
bool GameData::isLeftEdge(int r, int c) {
	if(c == 0) {
		return true;
	} else {
		return false;
	}
}

// HELPS TO MAKE CODE IN HANDLE EVENTS COMPACT
bool GameData::movePlayerUP(int a_playerNum) {
	bool canMoveThere = false;
	if(canMove(UP,m_gameBoard->getPlayer(a_playerNum).getPosition())){
		canMoveThere = true;
		m_gameBoard->getPlayer(a_playerNum).movePlayer(UP);
	}
	// check if that player is drakon, ignore arrows
	else if(a_playerNum == NUMBER_OF_PLAYERS && hasNeighbor(m_gameBoard->getPlayer(a_playerNum).getPosition(),UP)){
		canMoveThere = true;
		m_gameBoard->getPlayer(a_playerNum).movePlayer(UP);
	}
	return canMoveThere;
}

bool GameData::movePlayerRIGHT(int a_playerNum) {
	bool canMoveThere = false;
	if(canMove(RIGHT,m_gameBoard->getPlayer(a_playerNum).getPosition())){
		canMoveThere = true;
		m_gameBoard->getPlayer(a_playerNum).movePlayer(RIGHT);
	}
	// check if that player is drakon, ignore arrows
	else if(a_playerNum == NUMBER_OF_PLAYERS && hasNeighbor(m_gameBoard->getPlayer(a_playerNum).getPosition(),RIGHT)){
		canMoveThere = true;
		m_gameBoard->getPlayer(a_playerNum).movePlayer(RIGHT);
	}
	return canMoveThere;
}

bool GameData::movePlayerDOWN(int a_playerNum) {

		bool canMoveThere = false;
	if(canMove(DOWN,m_gameBoard->getPlayer(a_playerNum).getPosition())){
		canMoveThere = true;
		m_gameBoard->getPlayer(a_playerNum).movePlayer(DOWN);
	}
	// check if that player is drakon, ignore arrows
	else if(a_playerNum == NUMBER_OF_PLAYERS && hasNeighbor(m_gameBoard->getPlayer(a_playerNum).getPosition(),DOWN)){
		canMoveThere = true;
		m_gameBoard->getPlayer(a_playerNum).movePlayer(DOWN);
	}
	return canMoveThere;

}

bool GameData::movePlayerLEFT(int a_playerNum) {
	bool canMoveThere = false;
	if(canMove(LEFT,m_gameBoard->getPlayer(a_playerNum).getPosition())){
		canMoveThere = true;
		m_gameBoard->getPlayer(a_playerNum).movePlayer(LEFT);
	}
	// check if that player is drakon, ignore arrows
	else if(a_playerNum == NUMBER_OF_PLAYERS && hasNeighbor(m_gameBoard->getPlayer(a_playerNum).getPosition(),LEFT)){
		canMoveThere = true;
		m_gameBoard->getPlayer(a_playerNum).movePlayer(LEFT);
	}
	return canMoveThere;
}

void GameData::moveCamUP(void) {
	int x = m_gameBoard->getGridStart().getX();
	int y = m_gameBoard->getGridStart().getY();
	y += (TILE_BG_HEIGHT*TILE_IMAGE_MODIFIER_Y) + GRID_THICK_Y;

	m_gameBoard->setGridStart(y,x);
	m_gameBoard->drawGameGrid(m_buffer);
}

void GameData::moveCamRIGHT(void) {
	int x = m_gameBoard->getGridStart().getX();
	int y = m_gameBoard->getGridStart().getY();
	x -= (TILE_BG_WIDTH*TILE_IMAGE_MODIFIER_X) + GRID_THICK_X;

	m_gameBoard->setGridStart(y,x);
	m_gameBoard->drawGameGrid(m_buffer);
}

void GameData::moveCamDOWN(void) {
	int x = m_gameBoard->getGridStart().getX();
	int y = m_gameBoard->getGridStart().getY();
	y -= (TILE_BG_HEIGHT*TILE_IMAGE_MODIFIER_Y) + GRID_THICK_Y;

	m_gameBoard->setGridStart(y,x);
	m_gameBoard->drawGameGrid(m_buffer);
}

void GameData::moveCamLEFT(void) {
	int x = m_gameBoard->getGridStart().getX();
	int y = m_gameBoard->getGridStart().getY();
	x += (TILE_BG_WIDTH*TILE_IMAGE_MODIFIER_X) + GRID_THICK_X;

	m_gameBoard->setGridStart(y,x);
	m_gameBoard->drawGameGrid(m_buffer);
}

void GameData::centerCamOnPlayer(Player a_activePlayer) {
	Player tempPlayer = a_activePlayer;
	m_gameBoard->setGridFocus(Position(tempPlayer.getPosition().getX(),tempPlayer.getPosition().getY()));
	m_gameBoard->setGridStartPos();
	m_gameBoard->drawGameGrid(m_buffer);
}

// USED FOR STATE ACTION-VALIDITY CHECKING
bool GameData::isAnyState(GameState state_1) {
	if(m_currentGameState == state_1) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isAnyState(GameState state_1,GameState state_2) {
	if(m_currentGameState == state_1 || m_currentGameState == state_2) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isAnyState(GameState state_1,GameState state_2,GameState state_3) {
	if(m_currentGameState == state_1 || m_currentGameState == state_2 || m_currentGameState == state_3) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isAnyState(GameState state_1,GameState state_2,GameState state_3,GameState state_4) {
	if(m_currentGameState == state_1 || m_currentGameState == state_2 || m_currentGameState == state_3 || m_currentGameState == state_4) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isAnyState(GameState state_1,GameState state_2,GameState state_3,GameState state_4,GameState state_5) {
	if(m_currentGameState == state_1 || m_currentGameState == state_2 || m_currentGameState == state_3 || m_currentGameState == state_4
		|| m_currentGameState == state_5) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isAnyState(GameState state_1,GameState state_2,GameState state_3,GameState state_4,GameState state_5,GameState state_6) {
	if(m_currentGameState == state_1 || m_currentGameState == state_2 || m_currentGameState == state_3 || m_currentGameState == state_4
		|| m_currentGameState == state_5 || m_currentGameState == state_6) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isAllState(GameState state_1) {
	if(m_currentGameState == state_1) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isAllState(GameState state_1,GameState state_2) {
	if(m_currentGameState == state_1 && m_currentGameState == state_2) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isAllState(GameState state_1,GameState state_2,GameState state_3) {
	if(m_currentGameState == state_1 && m_currentGameState == state_2 && m_currentGameState == state_3) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isAllState(GameState state_1,GameState state_2,GameState state_3,GameState state_4) {
	if(m_currentGameState == state_1 && m_currentGameState == state_2 && m_currentGameState == state_3 && m_currentGameState == state_4) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isAllState(GameState state_1,GameState state_2,GameState state_3,GameState state_4,GameState state_5) {
	if(m_currentGameState == state_1 && m_currentGameState == state_2 && m_currentGameState == state_3 && m_currentGameState == state_4
		&& m_currentGameState == state_5) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isAllState(GameState state_1,GameState state_2,GameState state_3,GameState state_4,GameState state_5,GameState state_6) {
	if(m_currentGameState == state_1 && m_currentGameState == state_2 && m_currentGameState == state_3 && m_currentGameState == state_4
		&& m_currentGameState == state_5 && m_currentGameState == state_6) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isNoneOfState(GameState state_1) {
	if(m_currentGameState != state_1) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isNoneOfState(GameState state_1,GameState state_2) {
	if(m_currentGameState != state_1 && m_currentGameState != state_2) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isNoneOfState(GameState state_1,GameState state_2,GameState state_3) {
	if(m_currentGameState != state_1 && m_currentGameState != state_2 && m_currentGameState != state_3) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isNoneOfState(GameState state_1,GameState state_2,GameState state_3,GameState state_4) {
	if(m_currentGameState != state_1 && m_currentGameState != state_2 && m_currentGameState != state_3 && m_currentGameState != state_4) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isNoneOfState(GameState state_1,GameState state_2,GameState state_3,GameState state_4,GameState state_5) {
	if(m_currentGameState != state_1 && m_currentGameState != state_2 && m_currentGameState != state_3 && m_currentGameState != state_4
		&& m_currentGameState != state_5) {
			return true;
	} else {
		return false;
	}
}

bool GameData::isNoneOfState(GameState state_1,GameState state_2,GameState state_3,GameState state_4,GameState state_5,GameState state_6) {
	if(m_currentGameState != state_1 && m_currentGameState != state_2 && m_currentGameState != state_3 && m_currentGameState != state_4
		&& m_currentGameState != state_5 && m_currentGameState != state_6) {
			return true;
	} else {
		return false;
	}
}

void GameData::drawOverlay() {
	
	SDL_Surface * m_bufferCopyAlpha = SDL_ConvertSurface(m_buffer, m_buffer->format, SDL_SWSURFACE);
	
	// check which boxes it can go into
	
	
	
	isAnyState(MAGICAL_SHIFT_STATE)?checkValidPlacement3(m_grabbedTile):checkValidPlacement(m_grabbedTile);
	
		
		// draw overlay as green on each box
		for(int r = 0; r < BOARD_ARRAY_SIZE; ++r){
			for(int c = 0; c < BOARD_ARRAY_SIZE; ++c){
				
				if(m_validPlacement[r][c]){
					if(m_gameBoard->getPlayer(NUMBER_OF_PLAYERS).getPosition().equals(Position(c,r)) && m_gameBoard->isDrakonPlaced()){
						// dont draw if drakon player is on tile	
					}
					else{
						SDL_Rect pos = {m_gameBoard->getBoardTileXPos(c),m_gameBoard->getBoardTileYPos(r),m_gameBoard->getTileTrueWidth(),m_gameBoard->getTileTrueHeight()};
						SDL_FillRect(m_bufferCopyAlpha,&pos,OVERLAY_COLOR);
					}
				}
				
			}
		}
	
	SDL_Rect destRect = {0,0,0,0};

	SDL_SetAlpha(m_bufferCopyAlpha,SDL_SRCALPHA,OVERLAY_ALPHA);
	SDL_BlitSurface(m_bufferCopyAlpha,NULL,m_buffer,&destRect);
	SDL_FreeSurface(m_bufferCopyAlpha);

	resetValidPlacementArray();
}

Position GameData::convertScreenCoordsToGridPos(Position pos) {
	int row=0,column=0;
	int x=0,y=0;
	Position pos2 = Position(0,0);
	for(int r=0;r<BOARD_ARRAY_SIZE;++r) {
		for(int c=0;c<BOARD_ARRAY_SIZE;++c) {
			x = m_gameBoard->getBoardTileXPos(c);
			y = m_gameBoard->getBoardTileYPos(r);
			
			if(pos.getX() >= x && pos.getX() <= (x+m_gameBoard->getTileTrueWidth())) {
				if(pos.getY() >= y && pos.getY() <= (y+m_gameBoard->getTileTrueHeight())) {
					pos2 = Position(c,r);
				}
			}
		}
	}
	return pos2;
}
int GameData::getHandlistTileIndex(int mouseX, int mouseY){
	//PLAYER_TILE_LIST_START_X
	//int handEndX = PLAYER_TILE_LIST_START_X +TILE_BG_WIDTH*HAND_TILE_IMAGE_MODIFIER_X*PLAYER_TILE_LIST_DISPLAY_MAX;
	//int handEndY = PLAYER_TILE_LIST_START_Y+TILE_BG_HEIGHT*HAND_TILE_IMAGE_MODIFIER_Y;
	int index = -1;
	SDL_Rect handlistRect = {PLAYER_TILE_LIST_START_X,
							 PLAYER_TILE_LIST_START_Y,
							 (Uint16)(TILE_BG_WIDTH*HAND_TILE_IMAGE_MODIFIER_X*PLAYER_TILE_LIST_DISPLAY_MAX),
							 (Uint16)(TILE_BG_HEIGHT*HAND_TILE_IMAGE_MODIFIER_Y)};
	if(!isWithinRect(Position(mouseX,mouseY),handlistRect)){
		index = -1;
	}
	else{
		Mix_PlayChannel(-1,m_click,0);
		int handlistXcoord = mouseX - handlistRect.x;
		index = (int)floor(handlistXcoord / (TILE_BG_WIDTH*HAND_TILE_IMAGE_MODIFIER_X));
	}
	return index;
}
// Assuming it is within the rect of grid
Position GameData::convertScreenCoordsToGridPos(int mouseX, int mouseY) {
	int row=0,column=0;
	int x=0,y=0;
	Position pos2 = Position(0,0);
	for(int r=0;r<BOARD_ARRAY_SIZE;++r) {
		for(int c=0;c<BOARD_ARRAY_SIZE;++c) {
			x = m_gameBoard->getBoardTileXPos(c);
			y = m_gameBoard->getBoardTileYPos(r);
			
			if(mouseX >= x && mouseX <= (x+m_gameBoard->getTileTrueWidth())) {
				if(mouseY >= y && mouseY <= (y+m_gameBoard->getTileTrueHeight())) {
					pos2 = Position(c,r);
				}
			}
		}
	}
	return pos2;
}
void GameData::blit(SDL_Surface* a_source,SDL_Surface* a_destination,int a_x,int a_y) {
	SDL_Rect piece = {0,0,
		(Uint16)TILE_BG_WIDTH*(Uint16)HAND_TILE_IMAGE_MODIFIER_X,
		(Uint16)TILE_BG_HEIGHT*(Uint16)HAND_TILE_IMAGE_MODIFIER_Y};
	SDL_Rect pos = {a_x,a_y,0,0};
	SDL_BlitSurface(a_source, &piece, a_destination, &pos);
}
void GameData::blitImg(SDL_Surface* a_source,SDL_Surface* a_dest,int a_x,int a_y) {
	SDL_Rect destRect = {a_x,a_y,0,0};
	SDL_BlitSurface(a_source,NULL,a_dest,&destRect);
}
void GameData::undo() {
	m_gameBoard = m_oldGameBoard;
	m_currentGameState = CHOOSE_ACTION;
}
// assuming that it hasNeighbor() in that direction
GameTile GameData::getNeighbor(Position columnRow, arrowDirection dir){
	GameTile tempGT;
	if(dir == UP) {
		return m_gameBoard->getGameTiles()[columnRow.getY()-1][columnRow.getX()];
	}
	else if(dir == DOWN){
		return m_gameBoard->getGameTiles()[columnRow.getY()+1][columnRow.getX()];
	}
	else if(dir == LEFT){
		return m_gameBoard->getGameTiles()[columnRow.getY()][columnRow.getX()-1];
	}
	else if(dir == RIGHT){
		return m_gameBoard->getGameTiles()[columnRow.getY()][columnRow.getX()+1];
	}	
	else {
		////cout << "INVALID DIRECTION AT GameTile GameData::getNeighbor(Position columnRow, arrowDirection dir)\n";
		exit(0);
	}
	return tempGT;
}
// assuming that there hasTile()==true at the Position columnRow, 
// and that the tile placements are correct(arrows not facing each other)
bool GameData::canMove(arrowDirection dir, Position columnRow){
	// check if there is a neighbor in that direction (checks if it is also out of bounds) 
	bool canMoveThere = false;
	if(hasNeighbor(columnRow,dir)){
		// then check if the tile in the position that the player is standing has an exit to that tile
		Tile tileToCheckExits = m_gameBoard->getGameTiles()[columnRow.getY()][columnRow.getX()].getTile();
		canMoveThere = tileToCheckExits.hasExit(dir);
		if(tileToCheckExits.getFlag() == MASTER_KEY || tileToCheckExits.getFlag() == TELEPORT){
			canMoveThere = true;
		}
	}
	return canMoveThere;
}
list<GameTile> GameData::getPossiblePlayerMovements(Position posOnBoard){
	list<GameTile> neighbors;
	// check exits of that game tile
	Tile thisTile= m_gameBoard->getGameTile(posOnBoard);
	
	// WARNING position may be finicky
	if(canMove(UP,posOnBoard)){
		neighbors.push_back(getNeighbor(posOnBoard,UP));
	}
	if(canMove(DOWN,posOnBoard)){
		neighbors.push_back(getNeighbor(posOnBoard,DOWN));
	}
	if(canMove(LEFT,posOnBoard)){
		neighbors.push_back(getNeighbor(posOnBoard,LEFT));
	}
	if(canMove(RIGHT,posOnBoard)){
		neighbors.push_back(getNeighbor(posOnBoard,RIGHT));
	}
	// check if those exits lead to other tiles
	return neighbors;
}
bool GameData::canMoveOnce(Position posOnBoard){
	
	list<GameTile> list1 = getPossiblePlayerMovements(posOnBoard);
	return (list1.size() > 0);
}
bool GameData::canMoveTwice(Position posOnBoard){
	bool canMove2x = false;
	// go through neighbors and push onto list1
	list<GameTile> list1 = getPossiblePlayerMovements(posOnBoard);
	list<GameTile> list2;
	// go through list1 and check if each GameTile has neighbors 
	//		(if getPossiblePlayerMovements(thatPos).size() > 0) if so canMove2x=true
	if(list1.size() > 0){
		for(list<GameTile>::iterator it = list1.begin(); it != list1.end(); it++){
			list<GameTile> tempList = getPossiblePlayerMovements(it->getPosition());
			if(tempList.size() > 0) canMove2x = true;
		}
	}
	return canMove2x;
}

/* window */
void GameData::toggleFullscreen()
{
	if(m_windowed) {
		m_buffer = SDL_SetVideoMode(1920,1080,32,SDL_HWSURFACE | SDL_RESIZABLE | SDL_FULLSCREEN);
		m_windowed = false;
	}
	else if(!m_windowed) {
		m_buffer = SDL_SetVideoMode(1920,1080,32,SDL_HWSURFACE | SDL_RESIZABLE);
		m_windowed = false;
	}
}